线程可以安排它退出时需要调用的函数,这与进程可以用atexit函数安排进程退出时需要调用的函数是类似的。这样的函数称为线程清理处理程序(thread cleanup handler)。线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说他们的执行顺序与它们注册时的顺序相反。
void pthread_cleanup_push(void (*rtn)(void *arg), void *arg);
void pthread_cleanup_pop(int execute);
当线程执行以下动作时调用清理函数,调用参数为arg,清理函数rtn的调用顺序是由pthread_cleanup_push函数来安排的。
(1) the call to pthread_exit
(2) responds to cancellation request
(3) make a call to pthread_cleanup_pop with a nonzero execute argument
如果execute参数置为0,清理函数将不被调用。无论哪种情况,pthread_cleanup_pop都将删除上次pthread_cleanup_push调用建立的清理处理程序。
void *thr_fn2(void *arg)
{
printf("thread 2 start/n");
pthread_cleanup_push(cleanup, "thread 2 first handler");
pthread_cleanup_push(cleanup, "thread 2 second handler");
printf("thread 2 push complete/n");
if (arg != NULL)
{
pthread_exit((void*)2);
}
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
pthread_exit((void*)2);
}
int main()
{
void *tret;
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, thr_fn1, (void*)1);
pthread_create(&tid2, NULL, thr_fn2, (void*)1);
pthread_join(tid1, &tret);
printf("thread 1 exit code %d/n", (int)tret);
pthread_join(tid2, &tret);
printf("thread 2 exit code %d/n", (int)tret);
exit(0);
}