2
votes

How do I get the returned void pointer of the function that I pass the pthread_create?

static void* pthread_sendRequest(void* name){
    RequestChannel chan(*(string*) name, RequestChannel::CLIENT_SIDE);
    string returnValue = chan.send_request("Hi");
    return (void*) &returnValue;

}

pthread_create(thread, NULL, pthread_sendRequest, new string(&"worker #" [i]));

How do I get the return value, of pthread_sendRequest when it is passed to pthread_ create, so I can cast it back to a string pointer and get the actual string?

Does the void** in pthread_join(thread, void**) grab it for me?

3
There's not really something like a returned value from a thread function. If you need to exchange data between threads, use the parameters of the thread function. - πάντα ῥεῖ
If the start_routine returns, the effect is as if there was an implicit call to pthread_exit() using the return value of start_routine as the exit status. - pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_create.html. Also, as this is C++, std::thread t{func, std::ref(returnedData)}; and make func return void and take whatever data to return by reference. - chris
@chris IIRC trying to return any real values using this mechanism (e.g. allocated strings or such), besides constant error indicator references, didn't work well. I'm not really sure, but I stay off using this feature (I think it's mostly because void* is too vague). - πάντα ῥεῖ
@πάνταῥεῖ, It can have problems if the reference becomes dangling in the time the thread takes, so you have to be careful there, as always when using references. I haven't heard of any other problems. - chris

3 Answers

4
votes

As other answers have indicates, the value returned from the thread function can be captured by passing in a pointer to a buffer to obtain that returned value.

However, in your example, your thread function is returning a pointer to a non-static local variable, which is invalid (whether the function is executed in a thread or not) because once the function exits the local object no longer exists.

You could maybe do something like:

static void* pthread_sendRequest(void* name){
    RequestChannel chan(*(string*) name, RequestChannel::CLIENT_SIDE);
    string* returnValue = new string(chan.send_request("Hi"));
    return (void*) returnValue;

}

pthread_create(thread, NULL, pthread_sendRequest, new string(&"worker #" [i]));

// ...

void* temp = NULL;
pthread_join(*thread, &temp); 

string* returnValue = (string*) temp;

// when done with returnValue
delete returnValue;
1
votes

When you call pthread_join it takes a pointer to a void* into which that return value is copied. (The example linked from that page illustrates usage, but it's pretty obvious anyway).

1
votes

If func is returned, or calls pthread_exit, you can get the exit status in pthread_join

int pthread_join(pthread_t tid, void **thread_return);

tid is the identifier that pthread_create fills in.