Threads????



  • Hi

    ich wollte nen chat programmieren, habs auch soweit higekriegt.
    ABER ein Prob bleibt: der client empfängt die daten immer nur direckt nachdem der benutzer eine nachricht verschickt hat.

    Das heißt, wenn ein anderer client hallo und dann tschüss schreibt dann kommt das beim ersten client nicht direkt an, sondern erst nachdem er etwas geschrieben hat. Das sieht dann ungefähr so aus:

    Bitte schreiben sie etwas: wie geht es dir?
    Client 2 schreibt: hallo
    Client 2 schreibt: tschüss
    Bitte schreiben sie etwas:
    

    ich hab von threads gehört und, dass das die beste lösung sein soll, leider hab ich absolut keine ahnung von threads.
    Ich weiß nur, dass ein thread sozusagen ein 2. prozess in einem prozess ist. Sozusagen ein 2 in 1 prozess. Meine Idee war: Der eine thread wartet auf antwort vom server und der andere sendet zum server.

    Kennt jemand gute tutorials oder bücher über threads in C++???

    Mfg Yazoo



  • Im Moment gibt es leider nicht DEN Thread-Mechanismus für C++. Das ist Plattform bzw. Toolkit abhängig. Wenn Dir Boost was sagt schau mal unter http://www.boost.org/doc/libs/1_35_0/doc/html/thread.html, dann kannst Du Dir das mal ansehen.
    Ansonsten suche mal nach CreateThread (thx.@_matze) für Windows bzw. pthread_create für Posix-Threads unter Linux.



  • Tachyon schrieb:

    Im Moment gibt es leider nicht DEN Thread-Mechanismus für C++. Das ist Plattform bzw. Toolkit abhängig. Wenn Dir Boost was sagt schau mal unter http://www.boost.org/doc/libs/1_35_0/doc/html/thread.html, dann kannst Du Dir das mal ansehen.
    Ansonsten suche mal nach Create_Thread für Windows bzw. pthread_create für Posix-Threads unter Linux.

    Die Windows-Funktion heißt natürlich CreateThread. 😉



  • pthreads

    haben damit in schule selbst erfolgreich
    multithreaded chatserver mit räumen erstellt.

    super anleitung(!): http://www.pronix.de/pronix-24.html

    die anleitung hast du schnell durch, es ist echt gut erklärt. Damit schaffst du das locker.



  • XaTrIxX schrieb:

    pthreads

    haben damit in schule selbst erfolgreich
    multithreaded chatserver mit räumen erstellt.

    super anleitung(!): http://www.pronix.de/pronix-24.html

    die anleitung hast du schnell durch, es ist echt gut erklärt. Damit schaffst du das locker.

    ich wette das funtzt nicht mit windows oder?



  • ich hab ma in google createthread eingegeben und ein schönes tut gefunden, aber es funtzt nicht:

    Ich mache es genau so wie im tut beschrieben:

    hThread = CreateThread(NULL,
                             0,
                             ThreadFunc,
                             0,
                             0,
                             &dwThreadID);
    

    Compiler Fehler:

    "code.cpp": E2034 Konvertierung von 'unsigned long (__stdcall *)(void *,int,char * *)' nach 'unsigned long (__stdcall *)(void *)' nicht möglich in Funktion main(int,char * *) in Zeile 109
    "code.cpp": E2342 Keine Übereinstimmung des Typs beim Parameter 'lpStartAddress' ('unsigned long (__stdcall *)(void *)' erwartet, 'unsigned long (__stdcall *)(void *,int,char * *)' erhalten) in Funktion main(int,char * *) in Zeile 109
    

    dann hab ich es so probiert:

    hThread = CreateThread(NULL,
                             0,
                             ThreadFunc(0,argc,argv), // diese parameter übernimmt die funktion Thradfunk
                             0,
                             0,
                             &dwThreadID);
    

    Compiler Fehler:

    "code.cpp": E2034 Konvertierung von 'unsigned long' nach 'unsigned long (__stdcall *)(void *)' nicht möglich in Funktion main(int,char * *) in Zeile 109
    "code.cpp": E2342 Keine Übereinstimmung des Typs beim Parameter 'lpStartAddress' ('unsigned long (__stdcall *)(void *)' erwartet, 'unsigned long' erhalten) in Funktion main(int,char * *) in Zeile 109
    

    darf ich der funktion ThreadFunk etwa keine weiteren parameter geben???



  • Darfst du schon, aber nur in bestimmter Form, nämlich als void-Pointer (LPVOID). Du kannst dir allerdings eine Struktur basteln, die du dann für den Aufruf nach LPVOID castest und in der Thread Funktion wieder zurückcastest.

    Vgl. http://www.c-plusplus.net/forum/viewtopic-var-t-is-192328-and-highlight-is-createthread.html,
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-193855-and-highlight-is-createthread.html



  • Deine ThreadProc muss exakt dieses Interface haben:

    DWORD WINAPI ThreadProc(LPVOID lpParameter)
    

    Anders geht es nicht.



  • Man sollte unter Windows besser _beginthreadex benutzen.


  • Administrator

    Oder man benutzt boost::thread. Dann kannst du auch mehrere Parameter typsicher übergeben. Man kann dann sogar Objekte als "Funktion" (Funktor halt) übergeben.

    Es empfiehlt sich sowieso mal Boost anzuschauen 😉

    Ansonsten für alle WinAPI sachen, empfehle ich das WinAPI Forum und die MSDN.
    WinAPI: http://www.c-plusplus.net/forum/viewforum-var-f-is-4.html
    MSDN: http://msdn2.microsoft.com/de-de/library/default.aspx
    MSDN (CreateThread): http://msdn2.microsoft.com/de-de/library/ms682453.aspx

    Grüssli



  • hab das prob mit globalen variablen gelößt



  • bei meinem prog is ein neues prob, was jetzt nix mehr mit threads zu tun hat sondern eher mit der stdio.h:

    ich rufe die funktion auf:

    sprintf(buf2, "%s schreibt: %s\n",names[i],buf);
    

    Die Variablen existieren alle, aber in der buf2 steht nur drin:

    Name schreibt:
    

    Name is der inhalt von names[i], wenn ich die Funktion so aufrufe:

    sprintf(buf2, "schreibt: %s\n",buf);
    

    steht in buf2

    schreibt: (Der inhalt von buf)
    

    WHY???

    und was kann ich machen, dass in der buf2 drin steht:

    (Inhalt von names[i]) schreibt: (Inhalt von buf)
    


  • Für alle hier die CreateThread in C++ empfehlen:

    Böse Falle!

    Siehe: http://support.microsoft.com/?scid=kb%3Ben-us%3B104641&x=10&y=15


  • Administrator

    evilissimo schrieb:

    Für alle hier die CreateThread in C++ empfehlen:

    Böse Falle!

    Siehe: http://support.microsoft.com/?scid=kb%3Ben-us%3B104641&x=10&y=15

    Hmmm, danke für die Info. Muss ich mal ein paar meiner älteren Programme anschauen und allenfalls ein Update durchführen.

    Aber das ist dann wohl ein Grund mehr Boost zu benutzen 😃

    Allerdings, da geht es doch um die CRT, also C-Run-Time. Wenn man sich also an C++ hält, passiert nix?

    Edit: Noch was gesehen im Artikel

    APPLIES TO
    The C Run-Time (CRT), when used with:
    Microsoft Visual C++ 1.0 Professional Edition
    Microsoft Visual C++ 2.0 Professional Edition
    Microsoft Visual C++ 2.1
    Microsoft Visual C++ 2.2
    Microsoft Visual C++ 4.0 Standard Edition
    Microsoft Visual C++ 4.1 Subscription
    Microsoft Visual C++ 4.2 Professional Edition
    Microsoft Visual C++ 5.0 Standard Edition
    Microsoft Visual C++ 6.0 Service Pack 5

    Kommt also in 7.0, 7.1, 8.0 und 9.0 nicht mehr vor?

    @Yazoo,
    1. Neuer Thread aufmachen.
    2. Das ist eher C, als C++. In C++ solltest du es mal mit einem StringStream versuchen. Oder die Boost-Bibliothek verwenden ^^
    3. Das einzige was mir jetzt spontan einfallen würde: Ist buf2 gross genug?

    Grüssli



  • buf2 ist auf jeden fall groß genug,
    hier die deklarationen:

    char buf[256];
    char buf2[301];
    std::string names[MAX_CLIENTS];   //in jedes names objekt des strings kommen max 44 zeichen
                                      // MAX_CLIENTS ist in diesem fall als 10 definiert
    

    buf2 muss leider char sein, da ich das später mit nem TCP Socket verschicken möchte. Normalerweise armeite ich nur mit std::string in der string.h



  • der fehler is extrem strange ich habe grade ma ausprobiert was er macht wenn ich die reihenfolge der variablen vertausch also:

    sprintf(buf2, "%s schreibt: %s\n",buf,names[i]);
    

    jetzt steht in buf2:

    (inhalt von buf) schreibt: (inhalt von names[i])
    

    HHHHHHÄÄÄÄÄÄ?????????

    Wieso, das ergibt doch keinen sinn, dass es in dieser Reihenfolge funtzt und in der anderen nicht!!!



  • es gingen bis jetzt alle davon aus, dass names[i] ebenfalls ein C-string ist.
    du kannst an (s)printf keine std::strings übergeben, das erzeugt nämlich schlicht und einfach undefiniertes verhalten. verwende names[i].c_str() - oder steig gleich ganz auf std::strings um. wenn du die daten nur versendest, sollte ein konstanter C-string reichen (den liefert dir std::string::c_str()), willst du daten empfangen, kannst du diese in einen std::vector<char> speichern (der groß genug ist, sie zu fassen).



  • vielen, vielen dank, das wusste ich noch nicht.


Anmelden zum Antworten