Thread: Passing class member function to pthread_create

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    159

    Passing class member function to pthread_create

    Hi,
    I 'd like to pass a class member function to pthread_create which is called by another class member function of the same class.
    Code:
    class A{
    public:
    void * func1(void *parm);
    void  func2();
    };
    
    void A::func2(){
    ...
    pthread_create(threads, NULL, & func1, (void *)(parm));
    ...
    }
    But gcc will give error:
    error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.
    How to fix this error? Thanks!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You will not be able to do that directly, since pthread_create() only allows you to specify one argument, but you need two -- the "this" pointer and the arg itself. The general pattern is:

    Code:
    void *LaunchMemberFunction(void *obj)
    {
        MyClass *myObj = reinterpret_cast<MyClass *>(obj);
        return myObj->function();
    }
    But since you need to pass a parameter, you'll need a second level of indirection:

    Code:
    class MyLauncher
    {
    public:
        MyLauncher(MyClass *myObj, void *arg) : mObj(myObj), mArg(arg) {}
    
        void *launch() { return mObj->function(mArg); }
    
        MyClass *mObj;
        void *mArg;
    };
    
    void *LaunchMemberFunction(void *obj)
    {
        MyLauncher *myLauncher = reinterpret_cast<MyLauncher *>(obj);
        return myLauncher->launch();
    }
    
    MyClass myObj;
    void *myArg;
    MyLauncher launcher(&myObj, myArg);
    pthread_create(&thr, NULL, LaunchMemberFunction, &launcher);
    It kinda makes you want to rethink what you're doing, doesn't it?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    159
    Thanks brewbuck!
    Since the way you gave is indirect, are there other solutions?

    1. I've tried to make func1 as static member function, but since it uses non-static data member, so error follows.

    2. is there some wrapper on pthread library or its equivalence for C++? Is pthread library the best choice for multithreading in C++?

    Thanks!

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by lehe View Post
    1. I've tried to make func1 as static member function, but since it uses non-static data member, so error follows.
    Right, that won't work.

    2. is there some wrapper on pthread library or its equivalence for C++? Is pthread library the best choice for multithreading in C++?
    I'd say pthreads is still the right choice. The method I gave above could be made general by some careful templatizing.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You can of course also provide the LaunchMemberFunction() as a static function - but you still need to translate the static call and void * into object and member function call.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    IMO the best choice is Boost.Thread, which supports member functions through Boost.Bind without any problems.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    I usually create an abstract class of sorts, and each thread that I create inherits from that class. Since a thread is implemented via a subclass, having to pass parameters directly to the thread function isn't necessary. Example:

    Code:
    // Obviously not complete, but this should demonstrate the basic idea....
    class thread
    {
          public:
                thread() : code_(0) { }
                void start() { pthread_create(&pth_, NULL, thread::thread_router, reinterpret_cast<void*>(this)); }
                void join() { pthread_join(&pth_, NULL); }
                
                virtual int exec() = 0;
                int exit_code() { return code_; }
    
          private:
                static void* thread_router(void* arg);
                void exec_thread() { code_ = exec(); }
                pthread_t pth_;
                int code_;
    };
    
    void*
    thread::thread_router(void* arg)
    {
        reinterpret_cast<thread*>(arg)->exec_thread();
        return NULL;
    }
    
    
    class my_thread : public thread
    {
        public:
             my_thread(int arg1, int arg2) : arg1_(arg1), arg2_(arg2) { }
             virtual int exec();
        
        private:
             int arg1_, arg2_;
    };
    
    int
    my_thread::exec()
    {
         // use arg1_, arg2_....
         return 0;
    }
    
    
    my_thread thr(1, 2);
    thr.start();
    
    // Wait for it to complete...
    thr.join();
    Last edited by tjb; 03-27-2009 at 07:50 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. syntax to pass a member function pointer to another class?
    By reanimated in forum C++ Programming
    Replies: 4
    Last Post: 11-27-2003, 05:24 PM