PThread und Class



  • Hallo zusammen,

    habe ein Problem mit PThread und Classen. Habe folgenden Testcode:

    /*
     * threadtest.cpp
    */
    #include <pthread.h>
    #include <iostream>
    #include "threadtest.h"
    
    namespace test {
    
    ThreadTest::ThreadTest() {
    	// TODO Auto-generated constructor stub
    
    }
    
    ThreadTest::~ThreadTest() {
    	// TODO Auto-generated destructor stub
    }
    
    void ThreadTest::start(long *id) {
    	pthread_t thread;
    	pthread_create(&thread, NULL, run, (void *) id);
    }
    
    void *ThreadTest::run(void *runID) {
    	std::cout << runID << std::endl;
    	pthread_exit(NULL);
    	return NULL;
    }
    
    } /* namespace test */
    
    /*
     * threadtest.h
     */
    
    #ifndef THREADTEST_H_
    #define THREADTEST_H_
    
    namespace test {
    
    class ThreadTest {
    public:
    	ThreadTest();
    	virtual ~ThreadTest();
    	void start(long *id);
    	void *run(void *runID);
    };
    
    } /* namespace test */
    #endif /* THREADTEST_H_ */
    

    Beim compilieren bekomme ich folgende Fehlermeldung:

    ../src/threadtest.cpp:24:48: Fehler: Argument des Typs »void* (test::ThreadTest::)(void*)« passt nicht zu »void* ()(void
    make: *** [src/threadtest.o] Fehler 1

    Vielleicht kann mir jemand von euch sagen wo mein Fehler liegt.



  • Du kannst keine Memberfunktion als Start-Routine übergeben. Benutze dafür eine statische Funktion, in etwa so:

    void Thread::start()
    {
        // pthread_t thread_handle; sollte ein Member sein, du brauchst das Handle noch für andere Dinge
        pthread_create(&thread_handle, 0, &Thread::run, this); // Wir übergeben this als Argument
    }
    
    void Thread::run(void* t) // Diese Funktion muss static sein
    {
        static_cast<Thread*>(t)->some_func(); // Nun die Funktion des this-Objekts aufrufen
        return 0;
    }
    

    Den Sinn der Start-ID habe ich jetzt nicht verstanden. Außerdem würde ich das, was die Funktion Start macht, im Konstruktor erledigen.



  • Danke für deine schnelle Antwort.

    Habe es jetzt mal abgeändert und bekomme jetzt folgende Meldung:

    ../src/threadtest.cpp:23:54: Fehler: »void (test::ThreadTest::)(void)« kann nicht nach »void* ()(void)« für Argument »3« nach »int pthread_create(pthread_t*, const pthread_attr_t*, void* ()(void), void*)« umgewandelt werden
    make: *** [src/threadtest.o] Fehler 1

    void ThreadTest::start() {
    	pthread_create(&thread, NULL, &ThreadTest::run, this);
    }
    
    void ThreadTest::run(void* runID) {
    	std::cout << "test" << std::endl;
        return;
    }
    

    So sollte es eigentlich funktionieren laut deiner Anleitung. Was ist noch falsch?



  • Du hast die Funktion nicht static gemacht. Ich habe übrigens den Stern beim Rückgabetyp von run vergessen, die gibt natürlich void* zurück.



  • Hi,

    habe es jetzt getestet. Es funktioniert leider noch nicht.
    Bekomme immer folgende Meldung:

    undefined reference to `test::Thread::someFunktion()'

    someFunktion habe ich aber deklariert.

    void Thread::start(){
    	pthread_create(&thread,NULL,&Thread::run,this);
    }
    
    void *Thread::run(void *t) {
    	static_cast<Thread*>(t)->run();
    	return 0;
    }
    
    void someFunktion(){
     cout << "test";
    }
    

    was ist noch falsch daran?



  • Du hast das Thread:: bei der Definition vergessen 😃



  • oh danke für die schnelle Antwort.Dummer Anfängerfehler.



  • Hallo zusammen,

    funktioniert leider immer noch nicht.

    Mein Code sieht jetzt wie folgt aus:

    #include <pthread.h>
    #include "threadtest.h"
    
    int main() {
    	::test::ThreadTest test;
    	test.start();
    	return 0;
    }
    
    /*
     * threadtest.h
     */
    
    #ifndef THREADTEST_H_
    #define THREADTEST_H_
    
    namespace test {
    
    class ThreadTest {
    public:
    	pthread_t thread;
    	ThreadTest();
    	virtual ~ThreadTest();
    	void start();
    	static void *run(void *runID);
    };
    
    } /* namespace test */
    #endif /* THREADTEST_H_ */
    
    /*
     * threadtest.cpp
     */
    #include <pthread.h>
    #include <iostream>
    #include "threadtest.h"
    
    namespace test {
    
    ThreadTest::ThreadTest() {
    	// TODO Auto-generated constructor stub
    
    }
    
    ThreadTest::~ThreadTest() {
    	// TODO Auto-generated destructor stub
    }
    
    void ThreadTest::start() {
    	pthread_create(&thread, NULL, &ThreadTest::run, this);
    }
    
    void *ThreadTest::run(void* runID) {
    	std::cout << "test" << std::endl;
        return 0;
    }
    
    } /* namespace test */
    

    Ich bekomme zwar kein Fehler mehr beim Compilieren, aber nach dem Start erscheint auch die Ausgabe test nicht. Hoffe ihr könnt mir weiterhelfen.



  • Vermutlich liegt es daran, dass deine Runtime den Prozess beendet, wenn der Mainthread beendet wird. Die Lösung ist, im Mainthread auf den neuen Thread zu warten, das geht mit pthread_join.



  • Spricht etwas gegen C++0x und std::thread?
    Denn dann kann man auch sehr einfach Memberfunktionen über einen Thread starten.



  • Hallo Eth0n,

    was ist der Vorteil c++0x zu verwenden. Bin ganz neu im Thema c++, habe bis jetzt nur java Programmiert. Bis jetzt konnte ich c++0x Code noch nicht in eclipse cdt for linux nutzen. Eine Codecompleten funktioniert nicht und das Compilieren mach auch noch Probleme. Was für ein Editor ist für c++0x geeignet (Ubuntu user). Gibt es da andere Source files?



  • Gerade Eclipse ist (zumindest bei mir unter Mac OS) die beste IDE für C++0x. Auf Linux hab ich sie noch nicht ausprobiert.


Anmelden zum Antworten