Why does pthread_exit () rarely call SEGV when called after pthread_detach ()?

I get SEGV in C ++, which I cannot easily reproduce (this happens in about one out of 100,000 test runs) in my call pthread_join()as my application closes. I checked the errno value and it is zero. This works on Centos v4.

Under what conditions pthread_join()will receive SEGV? It may be some kind of race condition, as it is extremely rare. One person suggests that I should not call pthread_detach () and pthread_exit (), but I do not understand why.

My first working hypothesis was that it was pthread_join()called while pthread_exit()it was still working on another thread and that it somehow led to SEGV, but many stated that this was not a problem.

The faulty code that receives SEGV in the main thread during application exit looks something like this (with an error returning the return code for brevity):

// During application startup, this function is called to create the child thread:

return_val = pthread_create(&_threadId, &attr,
                            (void *(*)(void *))initialize,
                            (void *)this);

// Apparently this next line is the issue:
return_val = pthread_detach(_threadId);

// Later during exit the following code is executed in the main thread:

// This main thread waits for the child thread exit request to finish:

// Release condition so child thread will exit:
releaseCond(mtx(), startCond(), &startCount);

// Wait until the child thread is done exiting so we don't delete memory it is
// using while it is shutting down.
waitOnCond(mtx(), endCond(), &endCount, 0);
// The above wait completes at the point that the child thread is about
// to call pthread_exit().

// It is unspecified whether a thread that has exited but remains unjoined
// counts against {PTHREAD_THREADS_MAX}, hence we must do pthread_join() to
// avoid possibly leaking the threads we destroy.
pthread_join(_threadId, NULL); // SEGV in here!!!

In the child thread that connects when exiting, the following code is executed, which starts at the point above where it releaseCond()is called in the main thread:

// Wait for main thread to tell us to exit:
waitOnCond(mtx(), startCond(), &startCount);

// Tell the main thread we are done so it will do pthread_join():
releaseCond(mtx(), endCond(), &endCount);
// At this point the main thread could call pthread_join() while we 
// call pthread_exit().

pthread_exit(NULL);

The thread appeared correctly and error codes were not created during its creation during application launch, and the thread completed its task correctly, which took about five seconds before the application exited.

What can cause this rare SEGV and how can I program it against it. One complaint is that my pthread_detach () call is a problem, if so, how will my code be fixed.

+5
source share
3 answers

, :

  • pthread_create ( , ?)
  • attr - pthread_attr_t ( ? NULL?)
  • attr ,
  • pthread_detach pthread_join -

... "" pthread_join , , .

[]

pthread_detach :

* pthread_join *() * pthread_detach *() , , .

, , pthread_join documentation :

undefined, , * pthread_join *() .

, , , , .

, pthread_join pthread_detach, .

+4

pthread_join pthread_exit , " , ", , pthread_exit, , pthread_exit, , , .

, - ( Nemo), pthread_exit ( 315052) - . " pthread_join() pthread_exit()", .

0

, . , undefined , pthread_join pthread_exit. , pthread.

pthread_join:

return_val = pthread_create(&_threadId, &attr,
                            (void *(*)(void *))initialize,
                            (void *)this);
//...
pthread_join(_threadId, NULL); // SEGV in here!!!

, . , , main . pthread_join , undefined. , .

pthread_exit: Linux POSIX:

The implicit call to pthread_exit () is executed when a thread other than the thread in which main () was called returns from the initial procedure that was used to create it. The return value of the function should serve as a thread termination status.

The behavior of pthread_exit () is undefined if it is called from a cancel handler or destructor that was invoked as a result of an implicit or explicit call to pthread_exit ().

If the call is pthread_exitmade in the cleanup handler, you will have undefined behavior.

0
source

All Articles