Re: pthread_create() and class member functions....

From: Joern Adamczewski (J.Adamczewski@clri6a.gsi.de)
Date: Fri Oct 01 1999 - 09:50:19 MEST


Hello Anton!

Testing the root TThread class, we  made some experiences
running a class member function as a (Linux-)pthread, which might help you.

Since pthread_create (and also the TThread constructor) expects a C function to be run,
it needs the pointer to the class instance as function argument (4th argument of
pthread_create), if you want to run a member function of this C++ class.
When C++ methods are called from within a class, internally the class instance pointer
("this") is always passed as invisible first argument.
Thus  the "C" call of any C++ member function by pointer requires
the class object address as first argument...


For example,
in root TThread class, the implementation for pthreads (THREAD_PosixThread.cxx)
starts the member function void* TThread::Fun (which calls your own function
passed to the TThread constructor) as pthread with the pointer to the TThread instance
TThread* th as argument:
int ierr = pthread_create(&id, attr, &TThread::Fun,th);
(in method TPosixThread::Run(TThread* th))

Additionally, if you want to run a member void myfunction of any class Myclass as TThread,
you also have to pass the address to the class as function argument of TThread constructor,
since TThread::Fun uses a C function call to invoke your function:

 TThread* mythread= new TThread("My Thread",
         (void(*) (void *)) &Myclass::myfunction,
         (void*) &Myclass);
  mythread->Run();

when you create TThread from within class Myclass, you may write

TThread* mythread= new TThread("My Thread",
         (void(*) (void *)) &myfunction,
         (void*) this);
  mythread->Run();

The required cast of &myfunction produced a compiler warning in our tests
(egcs-2.91.66 Debian GNU/Linux (egcs-1.1.2 release)); however, the example
was compiled and runs.


I hope this may be useful for you;
best regards,
Joern

(Joern Adamczewski, go4 team DV&EE GSI Darmstadt)


KOSU_FOKIN@garbo.lucas.lu.se wrote:

> Hello rooters!
>
> I am trying to play around C++ implementation of posix threads and I realise
> that I can't pass a class member function into pthread_create() which takes an
> address of a function (void*) as the third argument. It says
>
> "builder.cxx", line 122: Error: Formal argument 3 of type void*(*)(void*)
> in call to pthread_create(unsigned*, const _pthread_attr*, void*(*)(void*), void*)
> is being passed void*(TVME::*)(void*).
>
> Could someone tell me how to solve the problem?
>
> It also says on the web in Linux FAQ
>
> F.2: I'm trying to use LinuxThreads from a C++ program, and the compiler complains about the third argument to pthread_create() !
> You're probably trying to pass a class member function or some other C++ thing as third
> argument to pthread_create(). Recall that pthread_create() is a C function, and it must be
> passed a C function as third argument.
>
> But that's rather strange ...
>
> I suppose that ROOT OO thread wrapper does this job. How?
>
> Best regards,
> Anton



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:40 MET