The following (pseudo-) code induces some behaviour which I dont understand. I have 2 threads running parallel. Both do the same (complex) calculation but I dont know which will finish first. Repeatedly run, there are cases where the first is faster and cases where the second is faster. This is okay and works as intended. Then, the first successfull thread should terminate the other thread and both should fork together. However if the first solver finishs, everything works out but if the second finishes first, the “join command” does not recognize that the first solver is terminated (so the join waits forever, the programm does not continue). Any ideas what I did wrong or what I could do different?
void* thread_function(...)
{
do_some_complex_task();
if (successfull && first_finsihed)
{
pthread_chancel(other_thread);
}
}
int main()
{
std::vector<pthread_t*> store;
store.resize(2);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_create(store[0], NULL, thread_function, ...);
pthread_create(store[1], NULL, thread_function, ...);
pthread_join(*store[0], NULL);
pthread_join(*store[1], NULL);
}
PS. If the pseudo code is not detailed enough please let me know.
Based on the pseudo code, one problem may be that the threads have deferred cancellation (the default value) instead of asynchronous cancellation. If the canceled thread never reaches a cancellation point, then
pthread_joinwould block. When callingpthread_create, the newly created thread inherits the calling thread’s:pthread_signmask)fenv)sched_setaffinity)Try invoking
pthread_setcanceltypefrom within threads you wish to cancel. You may also want to consider attaching a debugger to the program to identify the current state of the threads.Ideally, if it is at all possible, consider avoiding
pthread_cancel. Although the pthread-calls are documented, it can be difficult to obtain and maintain the exact behavior due to all of the minor details. It is generally easier to set a flag that indicates that the thread is set to exit, and begin to return from functions when it is set. Indo_some_complex_task, consider breaking the complex task into smaller tasks, and check for cancellation between each smaller task.