thread problem



  • Hallo ich habe eine Klasse in der befindet sich eine nicht statische funktion test(int a);

    diese soll in einem thread aufgerufen werden, dessen thread_func aber static ist.

    Hier der Code:

    A.h:

    class A{
    public:
    
    			//thread for storepacket
    			DWORD ThreadId;
    			HANDLE DataHandle;
    			void thread_start(int a);
    			//stop thread
    
    			static bool thread_stop();
                            void test(int a);
    private:
    			void test_2();
    			static DWORD WINAPI thread_func(LPVOID lpvoid);
    
    };
    

    A.cpp:

    void A::test(int a){
      a+=0.5; //just do something with a
    }
    
    void thread_start(int a){
      this->DataHandle = ::CreateThread(NULL,0,A::thread_func,&a,0,&this->ThreadId);
    
    }
    
    DWORD WINAPI A::thread_func(LPVOID lpvoid){
      int a = *((int*)lpvoid);
      test(a);
      return 0;
    }
    
    void A::test_2(){
       thread_start(20);
    }
    

    Als Fehler kommt:error C2352: 'A::test': Unzulässiger Aufruf einer nicht statischen Memberfunktion.

    Wenn ich nun die Thread function thread_func als nicht statisch deklariere, dann kommt folgender fehler:"A::thread_func": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&A::thread_func", um einen Zeiger auf den Member zu erstellen.

    Weiss jemand rat. Leider lässt sich die funktion test nicht als statisch deklarieren, der code ist an dieser stelle so gegeben. Ich will nur das diese Funktion in einem extra thread läuft. Danke im Vorraus!



  • hi

    du uebergibts dem thread als param die adresse von 'a'.
    uebergib anstatt nur dem a auch noch den this zeiger deines objektes.
    danach kannst du ueber die this-adresse auf das objekt zugreifen.
    du kannst nicht von einer statischen funktion aus auf eine nicht-statische ohne die objektadresse zugreifen

    Meep Meep



  • super danke funktioniert.

    Weisst du wie ich eine variable die in test_2 erst erstellt wird dem thread ebenfalls übergeben kann?

    this->DataHandle = ::CreateThread(NULL,0,A::thread_func,this,0,&this->ThreadId);

    also this plus dieser variablen.

    test_2(){
      int a;
      thread_start(this);
    }
    

    es soll a und der pointer zu this. Hierbei muss ich sagen dass ich es nicht als membervariable in der klasse zwischenspeichern kann, um dann später wieder über this draus zuzugreifen, da dieser wert in der zwischenzeit wieder neu geetzt worden sein könnte.



  • hallo

    mach dir ein struct mit dem this pointer und deiner variablen

    struct mein_struct
    {
       A *mein_this;
       int meine_variable;
    }
    
    mein_struct param;
    param.mein_this = &mein_objekt;
    param.meine_variable = 5;
    

    dann uebergibst du die adresse auf die struct deinem thread-parameter.

    Meep Meep



  • danke meep, fiel mir auch gerade ein, danke dir 👍



  • gibts eigentlich ne Möglichkeit im Nachhinein zu testen ob ein thread auf ein Handle bereits erstellt wurde?. der test :

    if (this->StorePacketDataHandle!= 0) 
    			{
    
    				::CloseHandle(this->StorePacketDataHandle);
    
    			}
    

    schlägt fehl weil wenn der pointer noch nicht initialisiert ist dann kommt ja igrendein he wert 0xfdfdf oder so raus.



  • also ehrlich gesagt weiß ich jetzt nicht was du willst.

    greenghecco schrieb:

    ein thread auf ein Handle bereits erstellt wurde

    was meinst du damit ?

    greenghecco schrieb:

    wenn der pointer noch nicht initialisiert ist

    du meinst mit dem pointer wohl this?
    wie kommst du an den this pointer ran, wenn du das objekt noch nicht erstellt hast ??

    Meep Meep



  • Ob HANDLE bereits gesetzt ist. Weil wenn das gesetzt wurde soll der thread gelöscht werden an dieser Stelle, um den thread erneut zu starten.



  • ich schaetz einmal das du mit HANDLE den threadhandle meinst, den du von CreateThread zurueckbekommen hast.
    aber warum willst du ihn loeschen wenn du einen handle bekommen hast ? du weißt ja nicht ob der thread mit seiner arbeit schon fertig ist.
    und loeschen und neu anlegen muss ansich auch nicht sein.
    mittels einer schleife, einem event und einem sync objekt kannst du ihn auch dauerlaufen lassen.
    du hast mir noch immer nicht gesagt was du mit dem pointer meintest.
    hol mal ein bisschen aus und erklaer mir mal was du da machen willst, viell. kann man das eleganter loesen.

    Meepp Meep



  • ja das problem ist das die funktion test_2 merhfach aufgerufen wird. Diese darf den thread nur dann neu starten wenn der vorherige fertig ist. Das Schütze ich zurzeit über einen Mutex. der Thread nimmt das Mutex und released es wenn er fertig ist. Die funktion test_2 zb läuft dann beim nächsten aufruf erst dann wenn der Mutex frei ist weiter und startet den thread wieder. Dazu muss er aber wissen und zwar beime ersten Anlauf, ob der Thread bereits einmal lief, sonst darf er das Handle ncicht closen. An und für sich hast du recht wenn du sagt inne while schleife packen und dort auf n go event warten. Das Mutex sorgt dann für den reibungslosen Ablauf. Das Mutex ist auch notwendig weil im Thread Daten behandelt werden die auch die funktion test_2 modifiziert. Deshalb darf nur einer auf die Daten zugreifen. Das Problem ist eigentlich jetzt der parameter int a, dieser wird in der Funktion test_2 erst erzeugt und dem thread übergeben. Aber wenn der thread schon läuft kann ich ihm das ja nicht jedes mal neu geben. Deswegen wollte ich in der funktion test_2 fragen ob das Mutex frei ist. Wenn ja dann closehandle und damit den thread löschen und ihn neu aufbauen. Ich kann natürlich parallel dazu auch einfach den Wert int a als memberattribut abspeichern und es so dem thread erst gar nicht übergeben. Dieser kann sich das Attribut dann zur Laufzeit holen, aber das wirkt auch nicht so elegant. Deshalb die Frage ob man shaun kann ob der thread bereits lief. Wenn nicht dann das Handle nicht löschen ansonsten löschen.



  • guck dir mal QueueUserAPC an. wenn ich dich richtig verstanden habe, darf nur ein thread laufen. mit QueueUserAPC kannst du das eventuel eleganter loesen. zu den variablen: reicht es wenn du mit ner kopie arbeitest ? dann kannst du dir den synchronisierungsteil sparen.

    Meep Meep



  • hm ja, hab das leider nicht ganz verstanden, seh das zum ersten mal, werde voerst erstmal ne globale variable initialisieren in einem anderen object, das setz ich auf 1 wenn der thread einmal lief, dann weis ich obs bereits initialisiert wurde.


Anmelden zum Antworten