POSIX-Threads in C++

Lateralus

Active Member
Hi

Ich würde gerne pthreads in C++ verwenden, habe aber Probleme mit der Definition der Funktionen, welche von pthread_create() aufgerufen werden sollen:

Beispiel:
pthread.cpp:
Code:
#include <iostream.h>
#include <unistd.h>
#include <pthread.h>

class Test{
	private:
	void *do_something_else(void *arg);
	
	public:
	
	void do_something();
};

void Test::do_something(){
	pthread_t thread1;
	
	pthread_create(&thread1, NULL, do_something_else, NULL);
	sleep(20);
	pthread_kill(thread1, SIGTERM);
}

void *Test::do_something_else(void *arg){
	while(1){
		cout << "thread sleeps...\n";
		sleep(3);
	}
}

Kompilieren:
Code:
g++ -Wno-deprecated pthread.cpp 
pthread.cpp: In member function `void Test::do_something()':
pthread.cpp:17: error: argument of type `void*(Test::)(void*)' does not match `void*(*)(void*)'

Wie genau müsste die Definition der Funktion statt

Code:
void *Test::do_something_else(void *arg){
...
}

aussehen?
 
Code:
pthread_create(&thread1, NULL, &do_something_else, NULL);

Du willst ja die Adresse der Funktion übergeben. Aber dann wirst Du sehn dass der Compiler sich beklagt von wegen "ISO C++ forbids taking address of non-static function" oder so ähnlich. Also musst Du die Methode do_something_else noch als "static" deklarieren.
 
ich bin mir zwar nicht sicher, aber wenn die Methode do_something_else() ein Mitglied der Klasse "test" ist und sie als Thread-Funktion verwenden willst, müsst sie eigentlich static sein, da es sonst Probleme mit dem "this"-Zeiger gibt.

Alternativ könntest du die Methoder außerhalb der Klasse definieren.


gruß,
grips
 
Zuletzt bearbeitet:
Dann musst Du einen Wrapper um die Thread Routine machen. Der übergibst Du dann this als Argument via pthread_create(). Dann machst Du einen cast auf ein Objekt Deiner Klasse und rufst die eigentliche Thread Routine auf.

Ich versuch mich mal kurz, ohne den Compiler zu bemühen:

Code:
class threaded {
  private:
    pthread_t thread;
    void *thread_routine(void);
    static void *thread_routine_wrapper(void *);
  (....)
};

static void
threaded::thread_routine_wrapper(void *arg) {
  threaded *ptr = (threaded *)arg;

  return (ptr->thread_routine());
}

Und irgendwo machst Du dann:

Code:
pthread_create(&thread, NULL, &thread_routine_wrapper, this);

Wenn Du den Thread im Konstruktor erzeugst kannst Du unabhängig agierende Objekte schaffen, quasi jedes im eigenen Thread.
 
Zurück
Oben