0

Suppose I have the following class:

*.h :

class MyClass{
    void caller();
    int threadProcuder(void *args);
};

*cpp :

void MyClass::caller()
{
    pthread_t i;
    pthread_create(&i,NULL,(void*(*)(void*))&MyClass::threadProcedure,(void*)this);
}

int MyClass::threadProcedure(void *args) 
{
    cout << "body of thread" << endl;
}

Unforunately, thread doesn't run.

John Conde
  • 217,595
  • 99
  • 455
  • 496

3 Answers3

5

The correct way is:

// Must declare the callback is extern "C" 
// As you are calling back from a C library.
// As this is compiles as C it can only call functions that use the C ABI
// There is no guarantee in the C++ standard that static member functions
// use the same ABI as a "C" function.
//
// Certain C++ ABI definitions do make this explicit but using this knowledge
// Renders your code non portable. If you use a C++ static member it will likely
// break in the future and when it does tracking down the problem will be nearly
// imposable.
extern "C" void* threadProcuder(void *args);

class MyClass{
    void caller();
    void* threadProcuder();
};

void MyClass::caller()
{
    // NOTE: This function should NOT be called from the constructor.
    //       You should really wait until the object is fully constructed
    //       before letting a thread run around inside your object
    //       otherwise the thread may will start playing with members that
    //       are not fully constructed.
    pthread_t i;
    pthread_create(&i,NULL,&threadProcedure,this);
}

void* threadProcuder(void *args)
{
    // I use reinterpret_cast<> here to make it stand out.
    // Others prefer static_cast<>. Both are valid and guaranteed to work.
    // Casting a pointer to/from void* is guaranteed by the standard
    MyClass* obj    = reinterpret_cast<MyClass*>(args);
    void*    result = NULL;
    try
    {
        result = obj->threadProcuder();
    }
    catch(...) {}   // you MUST catch all exceptions
                    // Failing to do so is very undefined.
                    // In most pthread_application allowing exceptions to escape
                    // usually (but not always) leads to application termination.
    return result;
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
1

EDIT: The function passed to pthread_create must be declared extern "C". See https://stackoverflow.com/a/2068048/786714 for a better explanation as to why this is the case.

You cannot use a static member-function as my original answer stated, though it may work as it its undefined behavior.

Community
  • 1
  • 1
alanxz
  • 1,966
  • 15
  • 17
  • 1
    `static` isn't sufficient. `pthread_create` is a C function, and takes a pointer to a C function. The function you pass it has to be `extern "C"`, so it cannot be a member, even `static`. – James Kanze Jul 31 '12 at 14:11
  • You can not use static member functions as the destion of pthread_create. If it happens to be working you are just getting lucky and it is non portable. See http://stackoverflow.com/a/6352434/14065 – Martin York Jul 31 '12 at 14:23
  • Oops, I guess I missed that. I'll edit my answer in a sec. For those wondering, here's a better explanation: http://stackoverflow.com/a/2068048/786714 – alanxz Aug 01 '12 at 14:32
0

I solved it, my format is correct, i didn't call in my constructor.

  • 1
    See http://stackoverflow.com/questions/11701766/pedantic-warning-and-pthread-create - your cast of a member function pointer is hiding a bug waiting to happen. – Michael Burr Jul 31 '12 at 14:26
  • class MyClass{ static void* threadProcuder(void* param); }; will work in your constructor and any type cast will not be needed – ChatCloud Jul 31 '12 at 14:31
  • 1
    @ActivationCloud: `Will seem to work`. Technically it is invalid and is non portable. See Michael's comment above and http://stackoverflow.com/a/6352434/14065 Try compiling with -pedantic and the compiler will also warn you about the problem. – Martin York Jul 31 '12 at 14:37
  • @LokiAstari: can `-pedantic` actually make g++ warn about using a pointer to a static member function with C++ linkage where a C function pointer is required? I tried it a few days ago hoping to get a warning, but didn't. Maybe some other `-W` option is necessary? – Michael Burr Jul 31 '12 at 22:54
  • @MichaelBurr: O man. I based my comment on your comment on the linked question. I had not actually tried it. – Martin York Aug 01 '12 at 00:08
  • please tell us how you managed to achieve this @m_pahlevanzadeh – moooeeeep Aug 01 '12 at 19:18
  • I explained it in above @moooeeeep –  Aug 03 '12 at 20:26