Kommunikation zwischen Threads



  • Hiho.

    Ich beschäftige mich gerade ein wenig mit Threadprogrammierung.

    Um einen Standpunkt zu setzen paste ich mal meinen Sourcecode.

    DWORD WINAPI FirstThread( LPVOID );
    DWORD WINAPI SecondThread( LPVOID );
    
    int main( int argc, string *argv[] )
    {
    	HANDLE hFirstThread, hSecondThread;
    	DWORD dwFirstThreadID, dwSecondThreadID;
    
    	tFirstThread = CreateThread( NULL, 0, FirstThread, 0, 0, &dwFirstThreadID );
    	tSecondThread = CreateThread( NULL, 0, SecondThread, 0, 0, &dwSecondThreadID );
    
    	CloseHandle( hSecondThread );
    	CloseHandle( hFirstThread );
    
    	_getch();
    
    	return 0;
    }
    
    DWORD WINAPI FirstThread( LPVOID data )
    {
    	return 0;
    }
    
    DWORD WINAPI SecondThread( LPVOID data )
    {
    	return 0;
    }
    

    Auch wenn meine beiden Threads zur Zeit noch nicht viel machen außer zu entstehen und wieder zu verpuffen - wie bekomme ich es hin unter den beiden Threads Informationen, genauer gesagt Variablen zu übergeben.

    Was mir noch wichtiger ist: ich möchte eine Variable in der main() deklarieren und sie in einem Thread ausgeben.

    Normaler Weise kann man Funktionen ja relativ einfach per Paramerter Variablen übergeben, da ein Thread jedoch nur mit Funktionszeiger erstellt werden habe ich keine wirkliche Idee dies zu realisieren.

    Ich dachte mir anfangs, man könnte sich eine "Transmitter"-funktion schreiben, die zwischen den Threads für jede Information einen neuen Thread öffnet. Dieser bleibt so lange offen bis die Information abgerufen wurde. Die ThreadID fungiert dann zur Identifikation. Aber das ist Irrsinn, es muss etwas einfacheres geben.

    Auf globales Arbeiten will ich zwingend verzichten, da ich sonst alles, was normalerweise in die main() gehört, außerhalb von allem setzten müsste.

    Das kanns also auch nicht sein.

    Nur um meine Vorstellung zu virtuallisieren ... so in etwa sollte es funktionieren. Dass es so nicht klappen kann ist logisch; dient also nur zur Veranschaulichung.

    DWORD WINAPI FirstThread( LPVOID );
    DWORD WINAPI SecondThread( LPVOID );
    
    int main( int argc, string *argv[] )
    {
    	HANDLE hFirstThread, hSecondThread;
    	DWORD dwFirstThreadID, dwSecondThread;
    
    	string main_var = "main";
    
    	tFirstThread = CreateThread( NULL, 0, FirstThread, 0, 0, &dwFirstThreadID );
    	tSecondThread = CreateThread( NULL, 0, SecondThread, 0, 0, &dwSecondThreadID );
    
    	CloseHandle( hSecondThread );
    	CloseHandle( hFirstThread );
    
    	_getch();
    
    	return 0;
    }
    
    DWORD WINAPI FirstThread( LPVOID data )
    {
    	string firstthread_var = "first";
    
    	cout << main_var;
    
    	return 0;
    }
    
    DWORD WINAPI SecondThread( LPVOID data )
    {
    	cout << firstthread_var;
    
    	return 0;
    }
    

    Gruß, teQUil4



  • Das geht nicht. Du könntest:

    Deinen Threads eine MessageQueue spendieren (so wie einem Windows-Programm) und dann Messages hin- und herschicken, oder

    einen Bereich definieren, auf den beide Threads Zugriff haben, entweder global, oder in der main-Funktion; im letzteren Fall übergibst Du dann den Threads beim Create einen Zeiger auf diese Daten.

    Aber auch, wenn Du Dich für Message-Queues entscheidest, mußt Du Dir überlegen, wie Du welchem Thread von der Existenz des/der anderen Threads Kenntnis gibst.

    Im Fall, daß beide/mehrere Threads auf gemeinsame Daten zugreifen sollen, mußt Du Dir überlegen, ob Synchronisation erforderlich ist und ggf. implementieren.

    Du könntest auch Thread 2 von Thread 1 aus erzeugen(ich zähle den Thread, der main ausführt, jetzt mal nicht mit) und dann Thread 2 einen Zeiger auf eine Stackvariable von Thread 1 übergeben, aber Vorsicht, wenn Thread 1 terminiert, ist der Speicher nicht mehr gültig.



  • Okay, eventuell kann man die Sache ja noch anders angehen, deshalb beschreibe ich mal kurz mein eigentliches Vorhaben.

    Mein Problem ist, dass ich nicht darauf warten kann, dass recv mal was empfängt ehe es weiter geht.

    Die beste Lösung, so dachte ich, ist ein eigenes Thread.

    Damit ich unabhängig von der main() bin, dachte ich mir, mache ich dazu noch ein extra Thread fürs Senden.

    Wenn ich jetzt etwas in dem recv Thread empfangen habe, liegt es in dem Buffer dieses Threads.

    Jetzt habe ich jedoch noch einen zweiten Socket. Dieser erhält ebenfalls für das Senden und Empfangen jeweils einen Thread. Insgesammt befinden sich also 4 Threads (mal ausgenommen dem main() Thread) im Programm.

    Das Empfangene aus dem ersten Socket und somit aus dem Recv Thread soll über den zweiten Socket versand werden. Da beides jeweils in einem seperaten Thread stattfinden soll um kein Delay zu erzeugen muss der Buffer an den Send-Thread des zweiten Sockets übergeben werden.

    Global möchte ich das nicht. Außerdem müssen beide Threads eines Sockets jeweils auf den Socket zugreifen können. Heisst, der Socket müsste global definiert werden. Ein unschöner Gedanke finde ich.

    Ich veranschauliche ja gerne. 😛

    http://img7.imageshack.us/img7/3590/veranschaulichung.jpg

    Vielleicht hat jemand noch eine bessere Idee.

    Wichtig ist nur, dass senden und empfangen praktisch gleichzeitig geschehen kann.

    Ich möchte nicht erst darauf warten etwas zu empfangen, denn unter Umständen muss ich erst etwas senden damit ich eine Antwort bekomme.

    Ich hoffe man versteht was gemeint ist.



  • Deine Erklärung ist im besten Fall verwirrend. Willst du noch von einem Socket A lesen und an einen Socket B senden, oder wie darf man sich das vorstellen?
    Und wozu so viele Threads? Benutze doch einfach poll() um zu schauen ob Daten auf dem Socket vorhanden sind, oder direkt eine Abstraktion darauf in Form von einer Bibliothek wie libevent.



  • Dieser Thread wurde von Moderator/in Marc++us aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hm. Also wie gesagt, mir ist es > im Grunde genommen < egal ob es in eigenen Threads stattfindet oder eben nicht.

    Wichtig ist nur, dass recv nicht den ganzen Programmablauf behindert weil es auf Daten wartet.

    Von poll und select habe ich bisher noch nichts gehört.

    Ich habe mich ein wenig via google und die Suchfunktion schlau gemacht, leider finde ich kein "Manual" in dem Sinne bezüglich dieser beiden Funkionen.

    Hast du ein Beispielcode zur Anwendung für mich?

    Wenn ich das richtig verstanden habe führt man durch poll bzw. select den recv für eine festgelegte Zeit in Millisekunden aus. Danach geht es einfach weiter.

    Durch eine nette while Schleife sollte man das ja hinbekommen.

    Welchen Timer sollte man dabei am besten verwenden, 10ms?



  • unlimieD.paSe schrieb:

    Wichtig ist nur, dass recv nicht den ganzen Programmablauf behindert weil es auf Daten wartet.

    Wenn Du von Socket A lesen willst um das Gelesene dann an Socket B weiterzusenden, ohne dass recv Dein Programm stilllegt, dann genügt aber doch ein Thread neben dem Thread, der main ausführt.

    Dieser zweite Thread ruft recv für Socket A auf und wartet, bis er Daten gelesen hat, dann sendet er die Daten an Socket B und kehrt zurück zum recv für Socket A(Schleife).

    'Gleichzeitig' lesen (A) und senden (B) würde bedeuten, daß Du die gelesenen Daten erst noch kopieren musst, sonst könnte es passieren, daß beim Lesen Daten überschrieben werden, die noch nicht gesendet sind.



  • Leider ist das nicht ganz so einfach.

    Anders herum soll es nämlich genau so funktionieren.

    Würde ich es so machen, wie von dir beschrieben, würde in dem Zusatzthread der Socket B entstehen und die Daten von Socket A in diesem Thread über Socket B gesendet werden.

    Jetzt soll aber der Socket B ebenfalls Daten empfangen und sie an Socket A weiterleiten damit er sie sendet.

    Praktisch wie ein ProxyServer, der alle Daten die er erhält an den jeweils anderen Socket weiterleitet um sie rauszusenden.

    Nur ist nicht bestimmt in welchen Abständen Daten kommen und ob evtl. 2 mal Daten empfangen werden bevor wieder was gesendet wird.

    Deshalb dachte ich, 2 Threads pro Socket wäre die beste Lösung.



  • unlimieD.paSe schrieb:

    Anders herum soll es nämlich genau so funktionieren.

    [...]

    Deshalb dachte ich, 2 Threads pro Socket wäre die beste Lösung.

    Also ein Thread, der in einer Schleife von Socket A liest und das Gelesene an Socket B sendet.
    Ein zweiter Thread, der in einer Schleife von Socket B liest und das Gelesene an Socket A sendet.

    Kommunikation zwischen den Threads ist dann nicht erforderlich. Sie müssen lediglich beim Create mit einem Zeiger auf eine Struktur versorgt werden, aus der hervorgeht, von welchem Socket sie lesen bzw. an welchen sie senden sollen.


Anmelden zum Antworten