Programm auf Standby gehen lassen und auf eingehende Nachricht warten



  • Hallo,

    ich habe (wie ihr euch ja denken könnt) ein Problem oder genauer 2.

    Erstmal die Beschreibung des "Projekts":
    Ich habe eine C++-Konsolenanwendung geschrieben, die eine "Schnittstelle" zwischen einem Netzwerkprogramm und einem anderen Programm (Matlab) herstellen soll. Das Netzwerkprogramm ist direkt eingebunden und mit Matlab wird über eine Pipe kommuniziert. Anders lies es sich leider nicht lösen...

    Ich habe dazu 3 Klassen: eine "Interface"-Klasse, die die Hauptklasse ist, eine "Network"-Klasse, die für die Kommunikation mit dem Netzwerkprogramm zuständig ist, und eine "PipeClient"-Klasse, die die Kommunikation über die Pipe ermöglicht. "Network" und "PipeClient" werden von "Interface" aus aufgerufen.

    Das Netzwrkprogramm kann jederzeit die "ReceiveMessage"-Funktion von "Network" aufrufen und so eine eingehende Nachricht übermitteln.

    Nun zu den Fragen:
    Zum einen, ist es möglich die eingehende Nachricht von Network an "Interface" zu übergeben und falls ja wie? Ein neues "Interface"-Objekt kann ich ja schlecht erstellen, da sonst wieder ein neues "network"-Objekt erstellt wird usw.
    Ein Lösungsansatz wäre natürlich eine "GetMessage"-Funktion, die die Nachricht zurückgibt aber geht es auch anders?

    Nun zum anderen, größeren Problem: es werden in unregelmäßigen Abständen Nachrichten sowohl von Matlab als auch vom Netzwerkprogramm eintreffen. Es kann z.B. passieren, dass eine halbe Stunde gar nichts los ist und dann plötzlich ganz viel.
    Daher suche ich nach einer effektiven und vor allem ressourcensparenden Möglichkeit, die Konsolenanwendung in einen "Standby"-Modus zu versetzen und auf eine Nachricht vom Netzwerkprogramm oder über die Pipe warten zu lassen.

    Vielen Dank schonmal fürs lesen und nachdenken, ich hoffe ich habe das ganze nicht zu konfus geschrieben 😉

    Cherup



  • Ich bin auch noch C++ Anfaenger, aber mir ist unklar, was deine Fragen mit C++ zu tun haben? Bei der letzten Frage wuerde ich einen Buffer einsetzen, der dann nach und nach die Aufgaben abarbeitet.



  • Hi,

    die Anwendung ist in C++ geschrieben, hat also was mit c++ zu tun 😉
    Die Idee mit dem Buffer verstehe ich nicht ganz. Die Abarbeitung der Aufgaben ist von der Geschwindigkeit her kein Problem, das Problem ist, dass die Anwendung warten muss bis es etwas zu tun gibt... und das vor allem ohne viel CPU-Zeit zu verbrauchen. Ich kann natürlich eine while-Schleife einbauen und darin abfragen ob neue Nachrichten da sind, aber die läuft dann ständig durch und beansprucht die CPU ohne wirklich was zu bringen und die CPU-Zeit brauche ich für andere Berechnungen in Matlab.



  • Achso, du hast Angst dass dein Programm 100% CPU-Last bei unnötigen Pollen von Nachrichten verbrät, dann bau einfach ein sleep in deine while Schleife ein.

    Zu C++, hier kommen halt nur Fragen rein, die was mit C++ an sich, also den Sprachfeatures zu tun haben.



  • Danke für die Antwort, das sleep hab ich irgendwie total vergessen obwohl ich das schon oft benutzt habe... Manchmal sieht man einfach den Wald vor lauter Bäumen nicht... 🙄

    Haben die Fragen denn nichts mit Sprachfeatures zu tun? Die Übergabe eines Strings aus einer Klasse an die aufrufende Klasse ohne eine neue Instanz der aufrufenden Klasse erstellen zu müssen oder eine Get-Funktion zu nutzen und eine Möglichkeit ein Programm quasi schlafen zu lassen sind doch Sprachfeatures oder nicht?



  • Für welches OS programmierst du denn?
    Und wie sieht die Kommunikation zwischen "Netzwerkprogramm" und deiner Software aus?
    Unter Windows brauchst du eigentlich nie ein Sleep, weil die Win32 entweder blockierende Aufrufe anbietet oder Event-gesteuert arbeitet.



  • Vielen Dank für die hilfreiche Antwort 🙂
    Ich arbeite unter Windows 7.
    Die Anbindung zwischen der Netzwerksoftware und meines Programms besteht durch includierte Header und einer DLL sowie einer Klassenvererbung einer Klasse der Netzwerksoftware, so dass ich mit meiner Klasse die entsprechenden Funktionen nutzen kann...
    Das mit den Events klingt für meine Zwecke sehr interessant. Gibt es eine Art "warte auf Event"-Funktion?
    Und wäre es möglich ein Codebeispiel zu Events zu posten? 😃
    Sonst werd ich wohl mal Tante Google zu dem Thema befragen, die weiß meisten Rat...



  • Cherup schrieb:

    Das mit den Events klingt für meine Zwecke sehr interessant. Gibt es eine Art "warte auf Event"-Funktion?

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx



  • Ich danke dir, das hilft mir ungemein weiter (ernst gemeint) 🙂



  • Dafür sind die Antworten in diesem Forum ja gedacht ...



  • Cherup schrieb:

    Vielen Dank für die hilfreiche Antwort 🙂
    Ich arbeite unter Windows 7.
    Die Anbindung zwischen der Netzwerksoftware und meines Programms besteht durch includierte Header und einer DLL sowie einer Klassenvererbung einer Klasse der Netzwerksoftware, so dass ich mit meiner Klasse die entsprechenden Funktionen nutzen kann...

    Wie sieht das technisch aus? Zeig uns doch bitte mal etwas Code, besonders den Teil, wo du Nachrichten (sowohl vom Netzwerkprogramm als auch von Matlab) empfängst und versendest.



  • Ich zeige euch gern den entsprechenden Code in komprimierter Form, der gesamte Code umfasst etwas über 1000 Zeilen. Aber die Frage ist was es dir bringt, da ich ja kein "Code"-Problem habe 🙂

    "Interface":

    class Interface{
            PipeClient *My_PipeClient = new PipeClient();
            Network *My_Network = new Network();
            Network->Connect(); //Verbindung zum Server
    
            //Hier wird das Evensystem noch eingebaut
            //Weiterleitung zwischen Network und PipeClient
    }
    

    "PipeClient":

    class PipeClient{
    	private:
                HANDLE pipe;
    	public:
    	    PipeClient(); // Verbindung zur Pipe
    	    ~PipeClient();
    
        //Hier wird mittels ReadFile() aus der Pipe gelesen
        //soll Event erzeugen sobald neue Nachricht eintrifft
        void sndMessage(wstring wMsg);
        //und hier mittels WriteFile() in die Pipe geschrieben
        wstring rcvMessage();
    };
    

    "Network":

    class Network : public Drittanbieterklasse {
             virtual void receiveInteraction (etliche Parameter)
             {
                ...
              /Hier wird ein Event erzeugt
             }
    };
    

    Ich denke mehr ist uninteressant, da es sich um sehr spezifischen Code handelt.

    Eine Frage habe ich dennoch:
    Blockiert WaitForSingleObject() oder kann in der Zeit anderer Code laufen? Das Problem ist nämlich, dass die Pipe regelmäßig abgefragt werden muss, ob eine neue Nachricht vorhanden ist um ein Event zu erzeugen. Zumindest kenne ich keine Funktion, die darauf wartet, das eine Nachricht in der Pipe ist. Falls jemand eine kennt, ich brauche sie 😃
    Und das führt mich zu einer anderen Frage: die Pipe muss ja regelmäßig abgefragt werden. Bin ich dann nicht quasi wieder am Ausgangspunkt, also einer While-Schleife mit sleep? Oder habt ihr da eine bessere Idee?

    Viele Grüße



  • Cherup schrieb:

    Eine Frage habe ich dennoch:
    Blockiert WaitForSingleObject() oder kann in der Zeit anderer Code laufen? Das Problem ist nämlich, dass die Pipe regelmäßig abgefragt werden muss, ob eine neue Nachricht vorhanden ist um ein Event zu erzeugen. Zumindest kenne ich keine Funktion, die darauf wartet, das eine Nachricht in der Pipe ist. Falls jemand eine kennt, ich brauche sie 😃
    Und das führt mich zu einer anderen Frage: die Pipe muss ja regelmäßig abgefragt werden. Bin ich dann nicht quasi wieder am Ausgangspunkt, also einer While-Schleife mit sleep? Oder habt ihr da eine bessere Idee?

    Ich glaube, das ist genau der Grund, warum Du nach Code gefragt worden bist ...
    Hast Du die Doku zu WaitFor... gelesen? Dort kannst Du doch entnehmen, dass Du es blockieren lassen kannst. Und nur dann kann ja auch 'in der Zeit anderer Code laufen' - oder in welcher Zeit soll der laufen, wenn die Funktion nicht blockiert?
    Du musst entweder in einer Schleife pollen, dort kann Dir die Wait-Funktion mit ihrem TimeOut aber das Sleep() ersparen, oder Du benötigst ein weiteres Konzept, nämlich Threads.
    Mit der Schleife wiederum brauchst Du eigentlich das Event-Konzept nicht, da tut es eine (globale Variable/übergebene Referenz) als Flag, dass etwas passiert ist, in Verbindung mit Sleep(), um die CPU nicht auszulasten.



  • Ok, dann hat sich das ja gelöst 😃
    Werde es mit einer Schleife machen, um mich in die Thread-Thematik einzulesen fehlt mir die Zeit...
    War aber trotzdem ein interessanter Exkurs zum Thema Events
    Es ist schon eine Weile her, dass ich mich so "tiefgehend" mit c++-Programmierung beschäftigt habe, daher habe ich bei Blockierung falsch herum gedacht, sry.
    Trotz des jetzt doch überflüssigen Event-Konzepts vielen Dank an alle, ich werde mich wieder melden falls noch mehr Probleme auftreten. 🙂



  • Herzlich gerne, aber gewöhn´ dir bitte an, mehr Details zu liefern. In diesem Beispiel wolltest du wissen, wie du möglichst ressourcenschonenden Code schreibst, hast uns aber nicht erzählt, wie dein bisheriges Vorgehen aussieht. Der von dir gezeigte Code hat keine weiteren Anhaltspunkte geliefert, weil nicht zu erkennen war, wie du die Daten empfängst/versendest. Gerade die interessanten Teile hast du ausgelassen.


Log in to reply