die Lieben Threads wollen mal wieder nicht....



  • mit einfachem

    (int)
    

    ging's aber! Danke für den Tipp!



  • -.-



  • Ich weiss Noobs sind lustig 😛



  • Lepetitmort schrieb:

    Ich weiss Noobs sind lustig 😛

    Hihi.

    Nee, es liegt an

    struct Job
    {
       int i;
       int j;
       int k;
    };
    ...
    Job job;//evtl besser mit new anlegen
    j.i=5;
    j.j=6;
    j.k=7;
    hThread[i] = CreateThread(NULL,0,ThreadFunc,&job,0, &dwThreadID[i]);
    

    und entsprechend

    DWORD WINAPI ThreadFunc(LPVOID data) 
    {
        Job* pjob=(job*)data;
        cout<<pjob->i;
        eigenefunktion(*****HIER*****); 
        return((DWORD)data); 
    }
    

    Also es ist üblich, in dem Parameter nur einen Zeiger auf die Nutzdaten zu verschicken, statt die Nutzdaten selber. Aber bei Dir reicht es ausnahmsweise mal, die Nutzdaten selber zu schicken. Das hat uns total verwirrt und wir haben aus Gewohnheit immer *data machen wollen.



  • Aaaaaaaaaaaaaaaaahhhhhh jetzt kommt's! Jetzt versteh ich den tieferen Sinn! Danke!



  • Lepetitmort schrieb:

    also ich mache einen neuen Thread auf:

    int i=1;
    hThread[i] = CreateThread(NULL,0,ThreadFunc,[b](LPVOID)i[/b],0, &dwThreadID[i]);
    

    Aufpassen: du übergibst da einen Zeiger auf eine lokale Variable.
    Die lokale Variable stirbt mit dem Scope in dem sie deklariert wurde.
    Der Thread läuft aber erst irgendwann an.

    Also entweder musst du das synchronisieren, oder du darfst keine globale Variable übergeben. Sonst kann (und wird) es passieren, dass der Thread die Variable zu einem Zeitpunkt ausliest, wo sie schon garnichtmehr existiert. Das ist dann 1) laut Standard "undefined behaviour" und 2) wird es auch real Probleme verursachen. Nämlich dass du oft mal nicht den Wert liest den du vor CreateThread reingeschrieben hast, sondern irgendwas ganz anderes. Bzw. der Extremfall wäre, dass dir das Programm einfach um die Ohren fliegt (Access Violation, z.B. wenn der Thread der CreateThread aufgerufen hat schon beendet wurde, wodurch der für den Stack reservierte Speicher freigegeben wird).

    Boost.Thread z.B. kapselt das alles schön, und gibt dir die Möglichkeit statt einer einfachen Thread-Funktion ein Funktionsobjekt. So kannst du z.B. mittels boost::bind Parameter an den Aufruf "binden", ohne dass irgendwelche Zeiger nötig wären.
    So kannst du auch Werte übergeben die aus lokalen Variablen kommen, ohne dass synchronisiert werden muss. (Bzw. ohne dass du dich darum kümmern musst - intern muss Boost.Thread auch ein paar Dinge synchronisieren.)


  • Administrator

    hustbaer schrieb:

    Aufpassen: du übergibst da einen Zeiger auf eine lokale Variable.

    Schreib dich nicht ab, lern lesen und schreiben 😃

    Schau mal ganz genau hin. Er castet den int-Wert in einen Zeiger. Er kopiert also den Wert und übergibt nicht einen Zeiger auf eine lokale Variable. Kann aber trotzdem gefährlich sein wegen Überläufen. Wurde übrigens bereits in den vorhergehenden Beiträgen erwähnt 😉

    Grüssli



  • Dravere schrieb:

    hustbaer schrieb:

    Aufpassen: du übergibst da einen Zeiger auf eine lokale Variable.

    Schreib dich nicht ab, lern lesen und schreiben 😃

    Schau mal ganz genau hin. Er castet den int-Wert in einen Zeiger. Er kopiert also den Wert und übergibt nicht einen Zeiger auf eine lokale Variable. Kann aber trotzdem gefährlich sein wegen Überläufen. Wurde übrigens bereits in den vorhergehenden Beiträgen erwähnt 😉

    Grüssli

    ROFL
    Du hast Recht 😃

    Naja, oft gemachter Fehler, da hab ich einfach mal das gelesen was meistens dortsteht, statt dem, was diesmal wirklich dortsteht.



  • Außerdem war der reflexartige Verweis auf boost und daß man immer und überall boost nehmen muß, hier wiedermal deplaziert.



  • volkard schrieb:

    Außerdem war der reflexartige Verweis auf boost und daß man immer und überall boost nehmen muß, hier wiedermal deplaziert.

    Wieso?
    Also mal davon abgesehen dass ich das nicht vorhandene "&" dazuphantasiert habe.

    Kennst du eine Library die es ähnlich einfach macht korrekt bestimmte Daten an einen neuen Thread zu übergeben?

    Davon abgesehen ... wo steht dass man immer und überall Boost verwenden muss? Ich finde die Boost einfach unheimlich praktisch, daher erwähne ich sie öfter. Wieso stört dich das?



  • volkard schrieb:

    Außerdem war der reflexartige Verweis auf boost ..., hier wiedermal deplaziert.

    Es gibt ein paar Themen wo ich den boost-Verweis für sinnvoll halte, gerade dort, wo einiges in den kommenden Standard einfließt. Und ich meine mich zu erinnern, das die Threadbibliothek im kommenden Standard der boost-Variante ähnelt. Zumal es sogar schon erste Bücher zu dem Thema gibt (wenn auch erst in Vorabversionen, z.B. habe ich hier das MEAP-PDF zu "C++ Concurrency in Action").


Anmelden zum Antworten