Threads Werte übergeben



  • Hallo,

    ich verstehe leider die Threadproblematik noch nicht wirklich...

    Ich weiß wie man einen Thread startet, das mache ich so:

    #include <cstdlib>
    #include <iostream>
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>
    #include <time.h>
    
    using namespace std;
    
    void th_daten();
    
    class Klasse
    {
    public:   
           int i;
    };
    
    int main()
    {
    //Hier meine Beispielklasse 
            Klasse testklasse;
            testklasse.i = 10;
    
    //Hier der Thread 
    	unsigned long threadId;
    
    	HANDLE hThread = CreateThread(NULL, 2000, (LPTHREAD_START_ROUTINE)th_daten, 0, 0, &threadId);
    
    	system("Pause");
    }
    
    void th_daten()
    {
        cout<<"Test Thread";	
    }
    

    Jetzt möchte ich die Werte der Klasse, namens "Klasse" :p, gerne in meinen Thread übergeben.
    Wenn ich also in meiner Main etwas verändere soll dies auch in dem Thread verändert werden, also mit Zeigern, oder so.

    Ich hoff ich hab mich eingigermaßen verständlich Ausgedrückt und bin auf die Antworten gespannt!



  • Schau dir mal CreateThread genau an! Da kannst du auch einen Parameter übergeben, und zwar einen void-Pointer (du übergibst hier 0). Du könntest also einen Pointer auf deine Klasse nach void* casten und an den Thread übergeben. In der Threadfunktion musst du ihn nur zurückcasten in den Typ deiner Klasse.

    Btw: http://blog.m-ri.de/index.php/2007/11/28/createthread-und-die-crt/



  • Ich weiß schon das man das überall nachlesen kann.
    Leider habe ich damit immer meine Probleme.
    Könntet ihr mir bitte mal an diesem spezielen Bespiel den Code reinschreiben?
    Ich hoffe das dauert nicht zu lange..
    Ich bin nämlich gerade am verzweifeln an dem Thema...



  • Hi,

    viel Spannender finde ich ja, wie man sowas threadsafe macht.... gibt es da ein gutes Konzept zur "kompletten Verantwortungsübergabe" an den neuen Thread?
    Ich habe da schonmal mit pthread-Mutexes&Co rumexperimentiert, bin aber letztlich nicht zum Ende gekommen (u.a., weil offensichtlich pthread-Mutexes nur in dem Thread unlocked werden kann, in dem er auch gelockt wurde).

    Gruß,

    Simon2.



  • Der Link hatte eigentlich einen anderen Zweck, nämlich den darauf hinzuweisen, dass die Verwendung von CreateThread gewisse Gefahren birgt und du lieber _beginthreadex nehmen solltest. Lies ihn dir bitte mal durch.

    Schau dir mal alles an, was ich auf die Schnelle geändert habe:

    #include <cstdlib>
    #include <iostream>
    #include <conio.h>
    #include <stdio.h>
    #include <windows.h>
    #include <time.h>
    
    using namespace std;
    
    void th_daten(PVOID pParam);
    
    class Klasse
    {
    public:   
    	int i;
    };
    
    int main()
    {
    	//Hier meine Beispielklasse 
    	Klasse testklasse;
    	testklasse.i = 10;
    
    	//Hier der Thread 
    	unsigned long threadId;
    
    	HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)th_daten, (PVOID)&testklasse, 0, &threadId);
    	WaitForSingleObject(hThread,INFINITE);
    	getchar();
    }
    
    void th_daten(PVOID pParam)
    {
    	Klasse *pClass=(Klasse*)pParam;
    	cout << "Test Thread" << endl;
    	cout << "Member i ist " << pClass->i << endl;
    }
    


  • void th_daten();
    HANDLE hThread = CreateThread(NULL, 2000, (LPTHREAD_START_ROUTINE)th_daten, 0, 0, &threadId);
    

    Was ist das eigentlich für eine Unsitte die Thread Funktion falsch zu dekl./def. und danach einfach zu casten? Das ist ja grauenhaft.

    Wenn die Thread Funktion die korrekte Signatur hat, wird der cast nicht benötigt.
    Alles andere ist einfach falsch.

    Simon



  • Der Trick laeuft ueber das letzte Argument von pthread_create:

    int pthread_create(pthread_t *restrict thread,
                  const pthread_attr_t *restrict attr,
                  void *(*start_routine)(void*), void *restrict arg);
    

    Du kannst dann etwa folgendes machen (ins Grobe geschmiert):

    class SomeThreadData
    {
        // Etwas an Daten
    
        public:
    
        void MakeSomething ();
    
    }
    
    void *MyThreatCall (void *pArgIn)
    {
    	parm  *pArgLoc = (parm *pArgIn) ;
    	pArgIn->MakeSomething ();
    	return NULL;
    }
    
    int main ()
    {
        pthread_t         thThread;
        pthread_attr_t    thAttr;
    
        SomeThreadData   *pMyThreadData;
    
        pMyThreadData = new SomeThreadData (/*Parameter ?*/);
    
        pthread_attr_init(&thAttr);
    
        pthread_create(&thThread, &thAttr, MyThreatPrg, (void *) SomeThreadData);
    
    }
    


  • hartmut1164 schrieb:

    ...

    Er benutzt aber offensichtlich Windows... 🙄



  • Das was _matze geschrieben hat war genau das was ich gesucht hatte.
    An dieser Stelle mal ein Dankeschön an alle.

    Jetzt suche ich bloß noch eine Funktion die alle Threads kurz stop (integriert in einem beliebigen Thread).
    Gibs da was kleines, enfaches?

    Zum Thema Sicherheit, ich weiß dass das was ich mache bestimmt nicht den optimalen Weg geht.
    Aber ich bin gerade am Anfang, deshalb erstmal die einfachen Sachen, Sicherheit ist ein Thema was ich mir für später aufhebe 😋



  • Frank879 schrieb:

    Das was _matze geschrieben hat war genau das was ich gesucht hatte.
    An dieser Stelle mal ein Dankeschön an alle.

    Jetzt suche ich bloß noch eine Funktion die alle Threads kurz stop (integriert in einem beliebigen Thread).
    Gibs da was kleines, enfaches?

    Unter pthread gibt es die Mutex-Funktionen, es sollte bei Win auch soetwas geben:

    http://www.xgc.com/manuals/xgclib/x5257.html


  • Administrator

    @hartmut1164,
    Die Dokumentation von pthread wird ihm aber nix nützen. Zudem würde ich eine Synchronization von Threads wohl eher über Events/Signals als über eine Mutex machen, zumindest auf Windows.

    @Frank879,
    http://msdn.microsoft.com/en-us/library/ms684847.aspx

    Sehr vorsichtige Verwendung, dann geht es damit:
    http://msdn.microsoft.com/en-us/library/ms686345.aspx
    http://msdn.microsoft.com/en-us/library/ms685086.aspx

    Besser wäre allerdings etwas wie Events/Signals zu verwenden. Mutex ist auch eine Option, aber ein Event ist meistens einfacher.
    Synchronizations Funktionen:
    http://msdn.microsoft.com/en-us/library/ms686360.aspx

    CreateEvent (weiter Funktionen dazu findet man im oberen Link unter der Kategorie Event oder unter "See also" auf dieser Seite):
    http://msdn.microsoft.com/en-us/library/ms682396.aspx

    Mit zum Beispiel WaitForSingleObject kannst du dann auf ein Event warten:
    http://msdn.microsoft.com/en-us/library/ms687032.aspx

    Grüssli



  • Dravere schrieb:

    @hartmut1164,
    Die Dokumentation von pthread wird ihm aber nix nützen. Zudem würde ich eine Synchronization von Threads wohl eher über Events/Signals als über eine Mutex machen, zumindest auf Windows....

    Und unter pthread?

    Gruß,

    Simon2.


  • Administrator

    Simon2 schrieb:

    Und unter pthread?

    Keine Ahnung, welche Möglichkeiten pthread bietet. Habe ich noch nie verwendet. Nur für UNIX habe ich noch nie programmiert und wenn es platformunabhängig sein soll, verwende ich Boost.Thread.

    Grüssli


Log in to reply