1

I'm trying to use the following:

pthread_create(&searchThread[i], &threadAttribs[i], DoStuff, &ParallelParams[i]);

If DoStuff is static it compiles but then I do not have access to any of the methods or variables that are part of the class that DoStuff is in. But if I keep DoStuff as a non-static method so that I can access everything else in the class I get the following compiler error:

error: argument of type 'void* (MyClass::)(void*)' does not match 'void* ()(void)'

where the error seems to be referring to the DoStuff argument and the fact that it's a member function.

Is there any hope of being able to pass in a non-static method allowing me access to everything in MyClass in my DoStuff method?

Thanks!

1 Answer 1

5

pthreads expects a void* startfunc(void*) signature and a non-static member function has the hidden this pointer so you have to get around that. An easy way is to create a static helper function in the class. Use that as the start function and pass the object you want to access in the 4th (data) parameter. Something like so:

class Foo
{
    public:

        void *runThis(void)
        {
            std::cout << "Thread accessing this member function" << std::endl;
            return 0;
        }

        static void *runHelper(void *classRef)
        {
            return ((Foo *)classRef)->runThis();
        }
};

int main(int argc, char *argv[])
{
    Foo foo;
    pthread_t t;

    pthread_create(&t, NULL, &Foo::runHelper, &foo);

    pthread_join(t, NULL);
}

There are some fancier template methods that amount to something like the above but are more generic.

Sign up to request clarification or add additional context in comments.

5 Comments

Technically this isn't valid, because the function pointer passed to pthread_create must be extern "C" which the static member function isn't ... but it works with GCC (and other compilers) due to a bug/feature that fails to differentiate between extern "C" and extern "C++" functions.
@JonathanWakely I thought in the case of GCC and other compilers it converts the function name in the pthread_create call to the function pointer at compile time. But the bug report you listed calls that view into question. Do you know if on some compilers function pointers are converted at compile time or handled at run time?
@ZacharyKraus, I'm not sure what you mean. Function pointers are handled at compile-time, but I don't see how that's relevant here, or in the linked bug report. The C++ standard says that an extern "C" function is a different type from an extern "C++" function, that's a static property of the type system, at compile-time. I don't know what run-time handling you are thinking of.
@JonathanWakely Here check out the first answer of this stackoverflow page: stackoverflow.com/questions/17119774/…. It explains how function pointers that are passed into pthread get converted at compile time to C style pointers if the conversion is possible. It also explains why you dont need to use extern "C" for most compilers. But, yeah technically based on the standard you are supposed to use extern "C". In this case due to the explanation in that post, you usually don't have to. That was all I was trying to say.
@ZacharyKraus, that answer is simply incorrect. There is no conversion performed, neither at compile-time nor run-time. The reason it's not needed is just a widespread and longstanding compiler bug, not because of some magic convertibility as the answer claims.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.