CreateThread - keine Memberfunktion erlaubt ?



  • Hmmmm schrieb:

    send calls setzten gerne mal strings zusammen und reissen sie ausseinander

    Die setzen weder was zusammen, noch reißen sie was auseinander. Sie senden einfach die Daten an den Empfänger.
    Aber: Wie ich oben schon mal in anderem Zusammenhang erwähnte, kann/darf man sich nicht darauf verlassen, dass ein Aufruf von recv haargenau das liest, was ein send geschickt hat.
    Stell Dir das so vor:
    send versendet die Daten an den Empfänger, die Daten werden in einem Puffer vorgehalten. Bei weiteren sends werden die nächsten Daten hinten angehängt, usw.

    recv beim Empfänger liest jetzt aus diesem Puffer. recv hat aber keine Ahnung davon, wieviel sends der Sender ausgeführt hat, es 'sieht' nur den Puffer und die darin befindlichen Daten und liest aus, was es kriegen kann.

    Das kann 1. dazu führen, dass zB mit einem send 1000 Byte versendet werden, ein recv aber nur 300 Byte liest. Deshalb - wie in einem früheren Posting erwähnt - braucht man für die Kommunikation häufig ein Protokoll. Etwa in der Art, dass beim send immer erst 4 Byte mit der Länge der folgenden Message gesendet wird, recv diese 4 Byte liest und dann so lange weiterliest, bis es genau die entsprechende Anzahl Byte bekommen hat.

    2. kann das zu dem von Dir beobachteten Verhalten führen, es wird zB 5 mal send mit je 1000 Byte ausgeführt; beim recv kann nun von 1 bis 5000 alles 'erwischt' werden ...



  • cooky451 schrieb:

    Wenn überhaupt, dann geht das so:

    class MyClass
    {
    public:
      static void foo(void *param)
      {
        std::cout << GetCurrentThreadId() << std::endl;
      }
    };
    
    int main()
    {
      for (int i = 0; i < 50; ++i)
        CreateThread(0, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(&MyClass::foo), 0, 0, 0);
      Sleep(20000);
      return 0;
    }
    

    Ich weiß aber nicht, welches Verhalten garantiert wird.

    Falls du die CRT nutzt, sollten eh _beginthread/ex etc. herhalten.
    Siehe
    http://msdn.microsoft.com/de-de/library/kdzttdcb(v=vs.80).aspx

    Der Herr Richter hatte glaube ich auch mal einen Blogeintrag dazu geschrieben..

    Nur so als Hinweis: Mit dem Cast nach LPTHREAD_START_ROUTINE den Kompiler zum Schweigen zu bringen ist nicht sehr nett. Verpasse der Thread Routine die korrekte Signatur, Rückgabetyp und Calling Convention und der Kompiler zeigt auch ohne Cast keinen Fehler mehr!!



  • Gut, dann werde ich wohl zum Anfang jeden Strings die größe mit übergeben. Dann sollte ich bei jedem recv()-call wohl auch prüfen ob rc < gesendeteGröße ist, wenn ja dann nochmal recv() callen, right ?

    Aber bei meinem vorhin erwähnten Problem komme ich immernoch nicht weiter.

    SendMessage ( GetDlgItem( hClientList[0] , ClientListBoxId ) , LB_DELETESTRING , 2 , 0 );
    

    -> Löscht immer das letzte Item der Listbox. Trotz des Hardcodings von index ( wPara ) ;O


  • Mod

    Hmmmm schrieb:

    SendMessage ( GetDlgItem( hClientList[0] , ClientListBoxId ) , LB_DELETESTRING , 2 , 0 );
    

    -> Löscht immer das letzte Item der Listbox. Trotz des Hardcodings von index ( wPara ) ;O

    Nö. Das tut es nicht...



  • Bei mir leider schon 😕

    Screeni : http://imageupload.org/?d=4A0697231



  • theta schrieb:

    ..

    Hast natürlich recht, sollte heißen:

    static unsigned long __stdcall foo(void *param)
    

    Ich nutze irgendwie immer nur _beginthread und war zu faul die richtige Signatur zu suchen 😉

    @Hmmmm
    Könntest du mir mal deinen ganzen Code (am besten gleich als VS Projekt, sonst halt einfach so) zuschicken (Mail über mein Profil)? Also falls das nicht irgendwie geheim sein soll oder so, denn das würde mich jetzt schon mal interessieren 😉



  • Okay, gerne ;P

    dazu muss ich mich aber eben erstmal reggen ( um deine Email zu sehen ) und das ganze compilefähig unter VSC++ 2010 machen. Ist immo immernoch unter devc++ und einige Sachen nimmt vsc++ nicht an ^^



  • Hi,..

    Nochmal etwas zu CreateThread und Memberfunktionen:
    http://www.c-plusplus.net/forum/278752

    Ich habe mir eine basisklasse geschrieben die ich als "handler" mit den methoden
    vererbe:

    class _thread_handler: public _thread_member_serializer
    {
    protected:
    
     HANDLE hThread;
     DWORD dwThreadId;
     _thread::LockedSignalStruct tssSignal;
    
    public:
    
    virtual DWORD WINAPI run(LPVOID lpParam=0); //=0;
    virtual start(BOOL BlockTillStartupSignaled=FALSE,DWORD dwTimeout=0,DWORD StackSize=0);
    virtual stop(BOOL BlockTillEndSignaled=TRUE,DWORD dwTimeout=5000);
    
    HANDLE _get_handle(void);
    DWORD _get_id(void);
    }
    

    tssSignal hat noch (Inlerlockabel) member die den startup signalisieren und im member run(thread) signalisieren das dieser beendet werden soll (muss natürlich jeden zyklus abgefragt werden) um ein unsauberes Terminate zu vermeiden...

    Damit kann man sauber und gut arbeiten ...

    grüüße 🙂



  • @ zeusosc ;O Sieht iwie nice aus 😉 Habe mich aber nur seeehr oberfächlich mit threads beschäftigt, ich glaube da kann man zieemlich in die Tiefe gehen

    Oh man ey ... wieso wollen denn all die Funktionen auf einmal TCHAR's -.- Ich muss das komplett alles umschreiben lal. Auch widestrings nehmen damit es unter VSC++ 2010 compiled. Neeeeeeeervt xD
    Heute abend sollte ich das fertig haben, dann schick ichs dir mal.



  • Hmmmm schrieb:

    Oh man ey ... wieso wollen denn all die Funktionen auf einmal TCHAR's -.-

    Dann hast du irgendwas "falsch" gemacht. (Wobei falsch jetzt bedeutet, dass du das Ziel hattest, dass die keine TCHARS wollen).

    Lege einfach ein leeres Projekt an, da musste nichts umschreiben.



  • Hmmmm schrieb:

    Oh man ey ... wieso wollen denn all die Funktionen auf einmal TCHAR's

    Weil Du Dein Projekt nicht von UNICODE auf Multibyte umgestellt hast. Musst mal in den Projekteinstellungen suchen.



  • Verdrehts nicht:
    TCHAR ist der "generiche" Zeichentyp - der ist entweder char oder wchar_t.



  • Jo, aber TE hat offensichtlich durchweg char benutzt, und das scheitert, wenn er sein Projekt als UNICODE - Projekt kompilieren will.



  • Yop, den Tipp mit dem Multibyte-compile hat mir auch grad jemand gegeben - compiled so einwandfrei ^^ Hat das noch irgendwelche Auswirkungen oder kann man das bedenkenlos verwenden ?



  • Du kannst Dein Projekt halt nur als Multibyte-Projekt kompilieren, so wie bisher mit Deinem DEV C++ auch.
    Setzt Du statt der char's WCHAR's ein, kannst Du nur UNICODE.
    Und TCHAR ist halt ein generischer Typ, der abhängig vom UNICODE - MAKRO in char oder WCHAR umgesetzt wird.
    Das heißt, wenn Du konsequent TCHAR benutzt, kannst Du Dein Projekt wahlweise als UNICODE-Projekt oder Multibyte(ANSI)-Projekt erstellen.
    Wenn Du da keinen Bedarf hast, lass es einfach bei char und Multibyte.



  • Ach, so macht das sinn ;P Danke für die Erläuterung !



  • Ach das Problem war, dass ich den Eintrag nicht vorher aus dem vector mit den Namen gelöscht habe ... sondern einfach nur die Lösch-Message an das Window geschickt habe. Dadurch wurde dann der Falsche eintrag gelöscht ^^


Anmelden zum Antworten