pthread_clean_push与pthread_cleanup_pop函数详解
测试,使用word2010发送博客文章
http://www.cnblogs.com/你的博客名称/services/metablogapi.aspx
转载http://blog.chinaunix.net/uid-26772137-id-3369725.html
-
#include <pthread.h>
-
void pthread_cleanup_push(void( *fn)(void*)),(void* arg))
-
-
void pthread_cleanup_pop(int excute)
-
这两个函数可以安排执行线程退出后需要执行的清理函数,这两个函数和进程退出时的atexit很像。
-
-
点击(此处)折叠或打开
-
#include <stdlib.h>
-
atexit(void(*fn)(void ));
-
"线程取消函数"即线程被取消或者下面描述的情况发生时自动调用的函数。它一般用于释放一些资源,比如释放锁,以免其它的线程永远也不能获得锁,而造成死锁。
-
pthread_cleanup_push()函数执行压栈清理函数的操作,而pthread_cleanup_pop()函数执行从栈中删除清理函数的操作。
-
在下面三种情况下,pthread_cleanup_push()压栈的"清理函数"会被调用:
-
1, 线程调用pthread_exit()函数,而不是直接return.
-
2, 响应取消请求时,也就是有其它的线程对该线程调用pthread_cancel()函数。
-
3, 本线程调用pthread_cleanup_pop()函数,并且其参数非0
-
注意:
-
1.当pthread_cleanup_pop()函数的参数为0时,仅仅在线程调用pthread_exit函数或者其它线程对本线程调用
-
pthread_cancel函数时,才在弹出"清理函数"的同时执行该"清理函数"。
-
2.注意pthread_exit终止线程与线程直接return终止线程的区别,调用return函数是不会在弹出"清理函数"的同时执行该"清理函数的。
-
3 .pthread_cleanup_push()函数与pthread_cleanup_pop()函数必须成对的出现在同一个函数中。
-
例子1.:
-
-
include <pthread.h>
-
-
#include <sys/types.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <errno.h>
-
-
#define handle_error_en(en, msg) \
-
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-
-
static int done = 0;
-
static int cleanup_pop_arg = 0;
-
static int cnt = 0;
-
-
static void cleanup_handler(void *arg)
-
{
-
printf("Called clean-up handler\n");
-
cnt = 0;
-
}
-
-
static void *thread_start(void *arg)
-
{
-
time_t start, curr;
-
-
printf("New thread started\n");
-
pthread_cleanup_push(cleanup_handler, NULL);
-
curr = start = time(NULL);
-
while(!done){
-
pthread_testcancel(); /* A cancellation point */
-
if(curr < time(NULL)){
-
curr = time(NULL);
-
printf("cnt = %d\n", cnt); /* A cancellation point */
-
cnt++;
-
}
-
}
-
-
pthread_cleanup_pop(cleanup_pop_arg);
-
return NULL;
-
}
-
-
int main(int argc, char *argv[])
-
{
-
pthread_t thr;
-
void *res;
-
-
pthread_create(&thr, NULL, thread_start, NULL);
-
sleep(2); /* Allow new thread to run a while */
-
-
if(argc > 1){
-
if(argc > 2)
-
cleanup_pop_arg = atoi(argv[2]);
-
done = 1;
-
-
}else{
-
printf("Canceling thread\n");
-
pthread_cancel(thr);
-
}
-
-
pthread_join(thr, &res);
-
if(res == PTHREAD_CANCELED)
-
printf("Thread was canceled; cnt = %d\n", cnt);
-
else
-
printf("Thread terminated normally; cnt = %d\n", cnt);
-
exit(EXIT_SUCCESS);
-
}
-
-
点击(此处)折叠或打开
-
#include<stdlib.h>
-
#include<stdio.h>
-
#include<unistd.h>
-
#include<pthread.h>
-
void clean_fun1(void * arg)
-
{
-
printf("this is clean fun1\n");
-
}
-
void clean_fun2(void * arg)
-
{
-
printf("this is clean fun2\n");
-
}
-
void * thread_fun(void * arg)
-
{
-
pthread_cleanup_push(clean_fun1,NULL);
-
pthread_cleanup_push(clean_fun2,NULL);
-
sleep(100);
-
//这里要注意,如果将sleep(100);换成while(1);的话,程序会一直暂停.push和pop要成对出现.
-
//因为while(1);运行的太快,线程不接受cancel信号
-
//while(1);
-
pthread_cleanup_pop(0);
-
pthread_cleanup_pop(0);
-
return NULL;
-
}
-
int main()
-
{
-
pthread_t tid1;
-
int err;
-
err=pthread_create(&tid1,NULL,thread_fun,NULL);
-
if(err!=0)
-
{
-
perror("pthread_create");
-
exit(0);
-
}
-
sleep(3);
-
//printf("test\n");
-
err=pthread_cancel(tid1);
-
if(err!=0)
-
{
-
perror("cancel error:");
-
exit(0);
-
}
-
err=pthread_join(tid1,NULL);
-
if(err!=0)
-
{
-
perror("pthread_join error:");
-
exit(0);
-
}
-
-
return 0;
-
}