C++ and pthreads

Programming, for all ages and all languages.
Post Reply
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

C++ and pthreads

Post by Alboin »

Hello!
I have been trying to create multiple threads in a C++ program I am developing. Moreover, I plan to create a nice class to enclose pthreads. However, when trying to pass a member function (virtual, non-virtual) to pthread_create I always get this error:

Code: Select all

mtkWindow.cc: In member function `void* mtkWindow::run()':
mtkWindow.cc:93: error: argument of type `void*(mtkWindow::)(void*)' does not
   match `void*(*)(void*)'
A cut down version of the class:

Code: Select all

class mtkWindow : public mtkWidget {
	private:
		pthread_t thread;			
		void *thread_main(void *arg);
	public:
		void *run();
		void main() {
			pthread_join(thread, NULL);
		}
};
And the Code:

Code: Select all

void *mtkWindow::run()
{
	pthread_create(&thread, NULL, thread_main, (void*)this);
}

void *mtkWindow::thread_main(void *arg)
{
	for(;;) {
		///Do whatever...
	}
}
I was reading about templates to solve the problem, but I think I am still stuck with it when I get down to pthread_create. I have also tried casting it to anything I could think of with no results :cry: ... Thanks!
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Hello,
I think I found a solution: instead of directly passing the member function to pthread_create, pass a extern "C" declared function to it with the this pointer as an argument. Then, in the extern "C" function call this->thread_main(). Thanks! (Sorry for posting a dud topic... :roll:)
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

The difference is that you're passing a member function pointer instead of a function pointer. The first requires the implicit "this" pointer, the second forbids it. To call the first requires an object to call it on. You can also make a static member function (that doesn't use a this pointer) instead. Your function doesn't even have to be extern "C", but just can't be in a class.

Code: Select all

class Thread {
    pthread_t thr;
    void start() {
        pthread_create(&thr, 0, &Thread::doRun, this);
    }
    static void *doRun(void *obj) {
        Thread *to = (Thread *)obj;
        obj->run();
    }
    virtual void run() = 0;
};
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Candy wrote:The difference is that you're passing a member function pointer instead of a function pointer. The first requires the implicit "this" pointer, the second forbids it. To call the first requires an object to call it on. You can also make a static member function (that doesn't use a this pointer) instead. Your function doesn't even have to be extern "C", but just can't be in a class.

Code: Select all

class Thread {
    pthread_t thr;
    void start() {
        pthread_create(&thr, 0, &Thread::doRun, this);
    }
    static void *doRun(void *obj) {
        Thread *to = (Thread *)obj;
        obj->run();
    }
    virtual void run() = 0;
};
... :shock: Really? I never realized that a member function and a normal function were so different.... Hmmm..... Maybe I should read up on my C++......
C8H10N4O2 | #446691 | Trust the nodes.
Post Reply