Problem mit Socket in Multithreading-Programm (boost)



  • Hallo!
    Ich habe hier ein kniffliges Problem:
    Ich schreibe momentan an einem Multithreading-Programm (mit boost), welches einen Socket besitzt, auf den beide Threads zugreifen können.
    Hier mal der genaue Ablauf:
    Es gibt 2 Threads: Thread 1 hat eine Schleife, welche immer wieder recv beim socket (blocking) aufruft und auf neue befehle wartet. Thread 2 sendet ab und zu mal etwas durch den socket und arbeitet an sonsten.
    Jetzt der Problemfall: Ich habe eine Situation, bei der Thread 2 etwas sendet, aber direkt darauf auf eine Antwort warten muss. Auch wenn Thread 2 jetzt ein recv macht, geht die antwort an thread 1, weil der zuerst da war. Kann mir jemand sagen, wie ich das Problem lösen könnte?
    Hatte nur eine Idee, in den Socket (ist eine Klasse) einen zweiten Puffer in den Socket zu pflanzen, wo thread 1 Nachrichten reinschreibt, die für thread 2 bestimmt sind und thread 2 dann die da raus lesen kann, aber das ist für mich keine befriedigende Lösung, vor allem, wenn später mal noch mehr threads auf den socket zugreifen sollen.
    Einen Mutex in die recv() funktion bauen hilft auch nichts, weil dann Thread 1 den mutex sperren würde, dann bei recv() hängen bleiben würde und wenn dann die Nachricht ankommt, geht die trotsdem an Thread 1, weil der bereits wartet.

    Vieleicht hat ja jemand von Euch eine Idee.

    MfG
    FloFri



  • 2 Sockets?



  • wird nix, weil das ein server ist. 😞



  • Vielleicht kannst du das Problem besser mit AIO lösen. Also das du nur einen Thread aufmachst und nicht dauernd liest, sondern nur wenn etwas vorhanden ist (Siehe man: poll(2), man: select(2), SIGIO, http://monkey.org/~provos/libevent/, http://www.fefe.de/fnord/enot.html, http://bulk.fefe.de/scalability/ etc.).

    Ansonsten bleibt dir wohl nichts anderes übrig, als das der eine Thread die Daten mitliest und an den anderen weiter leitet.



  • evtl. könnte Thread1 Thread2 kennen, und dann entsprechend
    die Daten weiterleiten. Bzw. Thread2 Thread1 bescheid sagt, das er jetzt
    was erwartet.



  • Ich muss mal etwas weiter ausholen, damit ihr einen überblick bekommt: In Thread 2 läuft ein LUA-Script, welches entsprechend C++-Funktionen aufruft. Thread 1 ist dazu da, so einen Thread wie Thread 2 zu erstellen, wenn der entsprechende Befehl durch den Socket kommt. Thread 2 und die entsprechenden Funktionen senden normalerweise einfach nur Daten zurück, die das Script ausgibt, aber bei einer Funktion muss das Script einen weiteren Wert vom Client anfordern. Und der kommt eben dann bei Thread 1 an, weil der ständig auf einen Befehl wartet um einen neuen Thread zu starten.
    Das ist der ganze Hintergrund.
    Um noch etwas genauer zu werden, was für eine Funktion das ist, was solche Probleme verursacht: Der Client ist eine MDI-Anwendung (wxwidgets). Jetzt gibt es eine Scriptfunktion mit dem Namen GUI.create, welche dafür sorgt, dass beim Client ein Neues Child-Fenster erstellt wird. So weit so gut, jetzt wartet aber die Funktion vom Script darauf, dass der Client eine Kennummer zurückgibt, damit das Script dem Client auch später sagen kann, auf welchem Child-Window die weiteren Aktionen ausgeführt werden sollen (Button erstellen, Eingabefeld erstellen, Fenster Schließen, etc.)

    Ich hoffe, das ist jetzt etwas verständlicher.



  • Ich würde an deiner Stelle von Thread 1 aus die Daten weiter reichen. Alles andere sorgt für synchronisations Probleme

    (Bsp:
    Server schickt "Erstelle Fenster"; Server erwartet ID
    Client sendet aber gleichzeitig "Erstelle neues Skript"
    Client antwortet entsprechend mit der ID.

    Nun sieht der Socket Buffer aber so aus: "Erstelle neues Skript";"ID")

    Warum machst du das nicht einfach so, dass du bei GUI.create dem Client die ID vorgibst, die er dann auf eine native-Window-ID mappen kann. Dann sparst du dir das ganze Kommunikationsproblem und das ummappen auf Client Seite sollte ja kein Problem sein.



  • Warum machst du das nicht einfach so, dass du bei GUI.create dem Client die ID vorgibst, die er dann auf eine native-Window-ID mappen kann. Dann sparst du dir das ganze Kommunikationsproblem und das ummappen auf Client Seite sollte ja kein Problem sein.

    Das ist eine Idee! Muss ich morgen, wenn ich in Ruhe vor dem Quellcode sitze schauen, ob ich das hinbekomme, sollte aber nicht all zu schwer sein, danke!


Anmelden zum Antworten