I create a thread to whom a void* to a structure is passed as argument. This structure is created in a class. When this class destructor is called, that is at the end of main, the structure is deleted. So later i see the child thread is launched again, and referring to its void* argument throws an exception as its already deallocated. I was hoping that the child threads gets exited before the destructors are called but that's not happening.
From Exitthread page in MSDN,
However, in C++ code, the thread is
exited before any destructors can be
called or any other automatic cleanup
can be performed.
whats the destructors the above line is referring to?
The child thread executes on a procedure that has a lifetime of the main thread. Using a global flag, i thought i could control the child thread execution. I set the global flag on the last routine that main thread executes. But does global objects get deallocated before the termination of child thread. In that case, even that wont help me.
To summarise, whats the best way i could exit a child thread which has the lifetime of the main thread? I do not want to use terminatethread api.
Edit: Some code sample
//In a method at end of main
void EndofMain()
{
WaitForSingleObject(globalObj->hMutex, INFINITE)
globalObj->threadActive = false;
ReleaseMutex(globalObj->hMutex);
}
void ChildThreadProc(void* data)
{
while(globalObj->threadActive)
{
WaitForSingleObject(globalObj->hMutex, INFINITE)
//do other stuff
ReleaseMutex(globalObj->hMutex);
sleep(1000);
}
}
Now is there a chance where globalObj is deallocated and then the child thread is called?
One option would be to have the main thread signal the child thread that it should exit (perhaps by setting a Boolean flag), then using WaitForSingleObject at the end of main() to wait for the thread to terminate before returning and calling the destructors. This prevents the error you've described by forcing the thread to exit (in a safe manner) before destructors fire.
Related
There is a main thread whose execution content CANNOT be controlled due to special irresistible reasons, that is, it has no ability to process any messages sent by child threads including events.
This main thread will create a child thread using windows-api _beginthreadex. This child thread that can perform any operation creates a form and is responsible for handling the windows message loop.
This child thread has a thread_local object. The destructor of this object must ensure that it is called, and this object is obtained like this:
obj_t get_tl_obj () {
thread_local obj_t tl_obj__;
return tl_obj__; // Copy constructor, not reference
}
If it is the return of the main thread, I can send a message to the child thread in the destructor of a global variable and wait for the child thread to end normally.
::PostMessage (hwnd, WM_CLOSE, 0, 0);
::WaitForSingleObject (taskhandle, 1024);
However, if the user closes the program by clicking the close button, the child thread will receives WM_CLOSE message and will release the window. At this point, I want the child thread to force the main thread to close.
I try to call the exit function directly, but in this way, although it can end the main thread and call the global destructor at the same time, the child thread itself is also forced to close, which will make the destructor of the thread_local object unable to be called.
So, I want to know, how can the child thread force the main thread to close after the child thread ends itself? Or do I need to create a thread specifically for this?
So I have a strange situation here. I have the following code:
int main()
{
std::shared_ptr<MyClassA> classA = std::shared_ptr<MyClassA>(new MyClassA);
std::shared_ptr<MyClassB> classB = std::shared_ptr<MyClassB>(new MyClassB(classA));
boost::thread_group threadGroup;
// This thread is essentially an infinite loop waiting for data on a socket
threadGroup.create_thread( boost::bind(&MyClassB::method1, classB) );
...do stuff
return 0;
}
MyClassB opens several resources, that are not deallocated when the program exits. However, if I remove the call to create_thread, the resources are deallocated. I put a printout in the destructor of MyClassB, and verified that it's not being called if that thread is created.
Anybody have any insight into what's going on here?
According to documentation boost::thread_group destructor destroys all onwed thread. boost::thread destructor in order:
if defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If *this has an associated thread of execution, calls detach(), DEPRECATED
BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to std::terminate. Destroys *this.
So you need to join threads explicitly. You can do that by calling boost::thread_group::join_all() at the end of your program.
Since you are passing shared pointer to class B to your thread, your thread now shares the instance. Until this threads exits NATURALLY, this resource will not be freed.
// This thread is essentially an infinite loop waiting for data on a socket
This comment is very telling. Your thread may run forever, well past the end of the program. If that's the case, you need to detach the thread before you exit main, and you should expect not to see the destructor called. The thread is still alive and shares ownership of that object.
...do stuff
If that ...do stuff doesn't involve either detaching or joining that thread, you are invoking undefined behavior in Boost. That undefined behavior becomes very well defined if you switch from using boost::thread to using std::thread.
That well-defined behavior is something that no sane programmer wants to invoke: Destructing a joinable thread results in a call to std::terminate(). The behavior of std::terminate is implementation-dependent, but typically it means "stop right now". Destructors aren't called, exit handlers aren't called.
You need to either join or detach that thread.
I have a program which creates a thread (I am using C++ Boost library for creating threads) when started. In the main program I have registered my cleanup function as.
atexit(cleanExit)
// Trap some signals for a clean exit.
signal(SIGQUIT, signalled)
signal(SIGABRT, signalled)
signal(SIGTERM, signalled)
signal(SIGINT, signalled)
static void signalled(int signal)
{
exit(signal)
}
static void cleanExit(void)
{
thread->interrupt();
thread->join();
}
As you can see above during the clean exit process I interrupt the thread and then wait here (in the main process) so that the thread does its clean up stuff. When I call thread->interrupt, my thread gets interrupted and I do the thread cleanUp stuff. Till here everything is working smooth and there is no problem.
But the problem comes in when I call the cleanup function in the thread. In the cleanup function I am sending some status back to a server, for that I have created a utility function, In this utility function I am accessing a "const static string" member of the class. The problem is when I access this const static string my application got just stuck. I have checked with strace and I am getting a Seg Fault. But when I change this "const static string" to "const string" my cleanup goes smooth.
QUESTION
What is the behavior of C++ "const static" once the program is terminated. Do they giveup when exit is called (which can be seen in above case) or any thoughts on this behavior.
UPDATE # 1
Here is the thread handler function. As I have mentioned above its a Boost thread.
try {
while ( true ) {
// Do your job here.
// 1: We can be interrupted.
boost::this_thread::interruption_point();
}
}
catch (boost::thread_interrupted const& )
{
// Before exiting we need to process all request messages in the queue
completeAllWorkBeforeExiting();
}
When the main program calls thread->interrupt, the thread will raise thread_interrupted exception at # 1, and catching this exception I am doing my cleanup stuff.
const does not affect when any object is destroyed.
static objects are destroyed in the order opposite to their order of creation. atexit essentially creates an anonymous static object with the given function as its destructor. That is, static object destructors and atexit callbacks occur in the order opposite their construction/registration.
It's completely unsafe to call exit from a signal handler. All the signal handler is practically allowed to do is set a flag which is later polled by the threads. As you've mentioned, the signal handler runs at interrupt time, so it might interrupt a system call. It might interrupt malloc in such a way that bypasses malloc's multithreading locks, since the reentrancy is on the same thread, not a different one as usually happens.
So that's a source of all sorts of unpredictable behavior. Without seeing more, I can't be more specific about what effect static is having, but it probably has something to do with changing the object's lifetime and/or instantiating it once per object.
I am getting a SEGV in C++ that I cannot easily reproduce (it occurs in about one in 100,000 test runs) in my call to pthread_join() as my application is shutting down. I checked the value of errno and it is zero. This is running on Centos v4.
Under what conditions would pthread_join() get a SEGV? This might be some kind of race condition since it is extremely rare. One person suggests I should not be calling pthread_detach() and pthread_exit(), but I am not clear on why.
My first working hypothesis was that pthread_join() is being called while pthread_exit() is still running in the other thread and that this somehow leads to a SEGV, but many have stated this is not an issue.
The failing code getting SEGV in the main thread during application exit looks roughly like this (with error return code checking omitted 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!!!
The child thread which is being joined on exit runs the following code which begins at the point above where 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 to come up properly and no error codes were produced during its creation during application startup and the thread performed its task correctly which took around five seconds before the application exited.
What might cause this rare SEGV to occur and how might I program defensively against it. One claim is that my call to pthread_detach() is the issue, if so, how should my code be corrected.
Assuming:
pthread_create returns zero (you are checking it, right?)
attr is a valid pthread_attr_t object (How are you creating it? Why not just pass NULL instead?)
attr does not specify that the thread is to be created detached
You did not call pthread_detach or pthread_join on the thread somewhere else
...then it is "impossible" for pthread_join to fail, and you either have some other memory corruption or a bug in your runtime.
[update]
The RATIONALE section for pthread_detach says:
The *pthread_join*() or *pthread_detach*() functions should eventually be
called for every thread that is created so that storage associated
with the thread may be reclaimed.
Although it does not say these are mutually exclusive, the pthread_join documentation specifies:
The behavior is undefined if the value specified by the thread
argument to *pthread_join*() does not refer to a joinable thread.
I am having trouble finding the exact wording that says a detached thread is not joinable, but I am pretty sure it is true.
So, either call pthread_join or pthread_detach, but not both.
If you read the standards documentation for pthread_join and pthread_exit and related pages, the join suspends execution "until the target thread terminates", and the thread calling pthread_exit doesn't terminate until it's done calling pthread_exit, so what you're worried about can't be the problem.
You may have corrupted memory somewhere (as Nemo suggests), or called pthread_exit from a cleanup handler (as user315052 suggests), or something else. But it's not "a race condition between pthread_join() and pthread_exit()", unless you're on a buggy or non-compliant implementation.
There is insufficient information to fully diagnose your problem. I concur with the other posted answers that the problem is more likely undefined behavior in your code than a race condition between pthread_join and pthread_exit. But I would also agree the existence of such a race would constitute a bug in the pthread library implementation.
Regarding pthread_join:
return_val = pthread_create(&_threadId, &attr,
(void *(*)(void *))initialize,
(void *)this);
//...
pthread_join(_threadId, NULL); // SEGV in here!!!
It looks like the join is in a class. This opens up the possibility that the object could be deleted while main is trying to do the join. If pthread_join is accessing freed memory, the result is undefined behavior. I am leaning towards this possibility, since accessing freed memory is very often undetected.
Regarding pthread_exit: The man page on Linux, and the POSIX spec state:
An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it. The function's return value shall serve as the thread's exit status.
The behavior of pthread_exit() is undefined if called from a cancellation cleanup handler or destructor function that was invoked as a result of either an implicit or explicit call to pthread_exit().
If the pthread_exit call is made in a cleanup handler, you will have undefined behavior.
What happens if we forcefully kill a running thread
I have a thread namely RecordThread() which calls some complex and time consuming functions. In these functions I am using try-catch blocks, allocating and deallocation memory and using critical section variables etc.
like
void RecordThread()
{
AddRecord();
FindRecord();
DeleteRecord();
// ...
ExitThread(0);
}
After creating this thread, I am immediately killing it before the thread completes its execution. In this case what happens if the thread is forcefully killed? Do the internal functions (AddRecord, DeleteRecord) complete their execution after we killed the thread?
After creating this thread, I am immediately killing it before the thread completes its execution.
I assume you mean you are using TerminateThread() in the following fashion:
HANDLE thread = CreateThread(...);
// ...
// short pause or other action?
// ...
TerminateThread(thread, 0); // Dangerous source of errors!
CloseHandle(thread);
If that is the case, then no, the thread executing RecordThread() will be stopped exactly where it is at the time that the other thread calls TerminateThread(). As per the notes in the TerminateThread() documentation, this exact point is somewhat random and depends on complex timing issues which are out of your control. This implies that you can't handle proper cleanup inside a thread and thus, you should rarely, if ever, kill a thread.
The proper way to request the thread to finish is by using WaitForSingleObject() like so:
HANDLE thread = CreateThread(...);
// ...
// some other action?
// ...
// you can pass a short timeout instead and kill the thread if it hasn't
// completed when the timeout expires.
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659%28v=vs.85%29.aspx
ExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, in C++ code, you should return from your thread function.
However the function calls will of course be completed because they're called before the ExitThread().
killing thread is the last resort - as Andre stated it leaves data in unknown state, you should never do that if thread works on shared object. Better choices are to notify thread to finish work by:
-using global volatile (important) variable which is changed only by main thread and tested by workers
-using signal type synchronization objects (mainly Events) also set by main thread and tested by workers
example of Thread that works well:
definition in *.h ------------------------------------
DWORD WINAPI Th_EspectroIF(LPVOID lpData);
CThread th_espectro(Th_EspectroIF);
use in *.cc -----------------------------------
DWORD WINAPI Th_EspectroIF(LPVOID lpData)
{
//Your code...
th_espectro.Stop(true);//stop this Thread
}
call the Thread with: th_espectro.Start();