C++, create a pthread for a function with a return

2020-05-29 11:51发布

问题:

Say I have the following function:

bool foo (int a); // This method declaration can not be changed.

How do I create a pthread for this? And how do I find out what the function returned? I've looked online and it seems like any function I want to create a pthread for must take a void* as an argument, and must return void* as well, and I'm not quite sure how the casting for all this would work, or where I would get the returned bool.

I'm new to C++, so please bear with me =)

回答1:

As far as you're dealing only with bools (which are, in fact, integers) it's possible, however not recommended, to cast the function to a pthread function type, as a pointer is compatible with (some) integer types:

pthread_t pid;
pthread_create(&pid, NULL, (void *(*)(void *))foo, (void *)argument));

However, you'd better wrap your function into another, pthread-compatible one, then return a pointer to its return value (must be free()'d after use):

void *foo_wrapper(void *arg)
{
    int a = *(int *)arg;
    bool retval = foo(a);
    bool *ret = malloc(sizeof(bool));
    *ret = retval;
    return ret;
}

then use:

pthread_t pid;
pthread_create(&pid, NULL, foo_wrapper, &a);

With this method, in the future you'll be able to call a function with arbitrary return or argument types.



回答2:

You could encapsulate the function you want to invoke in a function object, and then invoke that function object from within your pthread function:

First, define a function object that encapsulates your function call.

struct foo_functor {
    // Construct the object with your parameters
    foo_functor(int a) : ret_(), a_(a) {}

    // Invoke your function, capturing any return values.
    void operator()() {
        ret_ = foo(a_);
    }

    // Access the return value.
    bool result() {
        return ret_;
    }

private:
    bool ret_;
    int a_;
};

Second, define a function with the appropriate pthread signature that will invoke your function object.

// The wrapper function to call from pthread. This will in turn call 
extern "C" {
    void* thread_func(void* arg) {
        foo_functor* f = reinterpret_cast<foo_functor*>(arg);
        (*f)();
        return 0;
    }
}

Finally, instantiate your function object, and pass it as a parameter to the thread_func function.

foo_functor func(10);

pthread_t pid;
pthread_create(&pid, NULL, thread_func, &func);
pthread_join(pid, NULL);

bool ret = func.result();


回答3:

An easy work around is to use void* foo(int a, bool &b).



回答4:

A bool is functionally equivalent to an int. false is (usually) 0, and true is anything else. Thus

void *foo(void *a){
  int *a_int = (int *)a;
  //do things
  bool *x = new bool;
  *x = answer; 
  pthread_exit(x);
}

Then in your main you would get the returned result by casting it back to a bool.

bool *x; 
pthread_join(thread,(void *)x);
//Answer is *x