Clean up pthread resources when programme terminate
I have create a thread using pthread. My worker routine is a infinite loop. What is the design pattern to terminate and clean up all the resources开发者_Go百科 of the pthread when my main programme exit?
pthread_create(&thread, NULL, worker, NULL);
void* worker(void* arg){
while(true){
//do something
}
}
Thanks
I usually have a global variable which is initialised to true and set to false when you want the threads to exit and join to the threads from the main function. Pseudo-code below:
global isRunning = true
def main:
isRunning = true
id1 = startThread (worker)
id2 = startThread (worker)
id3 = startThread (worker)
joinThread (id1)
joinThread (id2)
joinThread (id3)
exit
def worker:
initialiseWorker()
while isRunning:
# something in here (or a signal handler) will
# set isRunning to false.
doSomeWork()
terminateWorker()
And make sure that threads do that loop in a timely fashion so that they can detect when they're supposed to exit. If they have long running jobs, you'll need to check periodically within doSomeWork()
as well. I make it a general rule that threads should exit within five seconds of being told to.
I don't ever kill threads from outside. There's too many problems that can be introduced. The global flag method lets each thread control itself since it's usually the only one that knows when it's safe to exit cleanly.
In addition to checking a switch, global or otherwise, pthreads has its own cancellation mechanism. Take a look at pthread_cancel(), pthread_setcancelstate(), pthread_setcanceltype(), pthread_testcancel(), pthread_cleanup_push(), etc.
The basic idea is the worker threads create (or use existing) cancelation points. If canceled, the thread's pushed cleanup handlers are called to clean up resources before exiting.
When your main program exits, all threads quit as well. This means that just one thread calling exit() (or if the main routine terminates) then other threads will quit.
You cannot just kill threads. If you kill threads which are doing work, then at best you get a memory leak, and at worst you get a deadlock. Either way it's not pretty.
Any resources which are cleaned up on process termination, will be cleaned up when the last thread exits (or if any thread calls exit() ). This includes memory (excluding shared memory, e.g. posix or sysv), file-like objects (if no other process has an open descriptor for them) and some other types of object.
Anything else which is persistent (e.g. temp files, some types of shared memory), you need to clean up yourself, either before you exit or (more robustly) at the beginning of the next run.
All the threads should come to an exit by their own or you will have to clean them manually. In first method you will have to use some global variable which will be secured using locks to tell the threads to stop execution. Something like this will be inside your while(true) loop in each thread.
while(true)
{
GetLock(SomeGlobalVariable);
if(SomeGlobalVariable == true)
{
unlock(SomeGlobalVariable);
break;
}
unlock(SomeGlobalVariable);
}
In the second method you will have to keep track of all the threadIds that you have created in an array and then at the time of exit kill all these ids one by one.
If your program is going to use many threads then you better go for the thread pool. In thread pool you create some threads at the beginning of the program and then when it is needed you give the thread and when the work is done the thread resource is given back.
There are libraries for this. e.g. http://threadpool.sourceforge.net/
精彩评论