pthread_cleanup_push与pthread_cleanup_pop的目的 作用

首先你必须知道pthread_cleanup_push与pthread_cleanup_pop的目的(作用)是什么。

比如thread1:
执行
pthread_mutex_lock(&mutex);

//一些会阻塞程序运行的调用,比如套接字的accept,等待客户连接
sock = accept(......);            //这里是随便找的一个可以阻塞的接口

pthread_mutex_unlock(&mutex);
这个例子中,如果线程1执行accept时,线程会阻塞(也就是等在那里,有客户端连接的时候才返回,或则出现其他故障),线程等待中......

这时候线程2发现线程1等了很久,不赖烦了,他想关掉线程1,于是调用pthread_cancel()或者类似函数,请求线程1立即退出。

这时候线程1仍然在accept等待中,当它收到线程2的cancel信号后,就会从accept中退出,然后终止线程,注意这个时候线程1还没有执行:
pthread_mutex_unlock(&mutex);
也就是说锁资源没有释放,这回造成其他线程的死锁问题

所以必须在线程接收到cancel后用一种方法来保证异常退出(也就是线程没达到终点)时可以做清理工作(主要是解锁方面),pthread_cleanup_push与pthread_cleanup_pop就是这样的。

pthread_cleanup_push(some_clean_func,...)
pthread_mutex_lock(&mutex);

//一些会阻塞程序运行的调用,比如套接字的accept,等待客户连接
sock = accept(......);            //这里是随便找的一个可以阻塞的接口

pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0);
return NULL;
上面的代码,如果accept被cancel后线程退出,会自动调用some_clean_func函数,在这个函数中你可以释放锁资源。如果accept没有被cancel,那么线程继续执行,当pthread_mutex_unlock(&mutex);表示线程自己正确的释放资源了,而执行pthread_cleanup_pop(0);也就是取消掉前面的some_clean_func函数。接着return线程就正确的结束了。

不晓得你明白没,通俗点就是:
pthread_cleanup_push注册一个回调函数,如果你的线程在对应的pthread_cleanup_pop之前异常退出(return是正常退出,其他是异常),那么系统就会执行这个回调函数(回调函数要做什么你自己决定)。但是如果在pthread_cleanup_pop之前没有异常退出,pthread_cleanup_pop就把对应的回调函数取消了,

关于取消点的解释:

比如你执行:
        printf("thread sleep\n");
        sleep(10);
        printf("thread wake...\n");
在sleep函数中,线程睡眠,结果收到cancel信号,这时候线程从sleep中醒来,但是线程不会立刻退出。这是应为pthread与C库方面的原因(具体是啥我也不清楚),pthread的建议是,如果一个函数是阻塞的,那么你必须在这个函数前后建立取消点,比如:
        printf("thread sleep\n");
        pthread_testcancel();
        sleep(10);
        pthread_testcancel();
        printf("thread wake...\n");
这样,就添加了两个取消掉。在执行到pthread_testcancel的位置时,线程才可能响应cancel退出进程。

额外的知识:
对于cancel信号,线程有两种方法: 忽略,和响应。默认是响应
接收到cancel信号,线程有两种处理类型: 立即响应 和 延迟响应(在最近的取消点响应),默认是延迟响应

pthread_cleanup_pop(0);不会调用清理函数,非零才调用

pthread_cleanup_push函数与pthread_cleanup_pop函数问题

10-30

#includern#includern#includernrnvoid cleanup(void*arg)rnrnrn printf("NO.%d clean up procdure\n",*(int*)arg);rnrnrnrnvoid*tfn1(void*arg)rnrnint a=1;rnprintf("the first thread\n");rnpthread_cleanup_push(cleanup,&a);rnrna=2;rnpthread_cleanup_push(cleanup,&a);rnrnreturn NULL;rnrnpthread_cleanup_pop(0);rnpthread_cleanup_pop(0);rnrnreturn NULL;rnrnrnrnvoid *tfn2(void*arg)rnrnrnint a=1;rnprintf("the second thread\n");rnpthread_cleanup_push(cleanup,&a);rnrna=2;rnpthread_cleanup_push(cleanup,&a);rnrnpthread_exit(NULL);rnrnpthread_cleanup_pop(0);rnpthread_cleanup_pop(0);rnrnrnreturn NULL;rnrnrnvoid*tfn3(void*arg)rnrnint a=1;rnrnprintf("the third thread\n");rnpthread_cleanup_push(cleanup,&a);rnrna=2;rnpthread_cleanup_push(cleanup,&a);rnpthread_cleanup_pop(1);rnrnprintf("ready to sleep\n");rnsleep(10);rnpthread_cleanup_pop(0);rnrnreturn NULL;rnrnrnint main()rnrnpthread_t tid1,tid2,tid3,tid4;rnint err;rnrnrnerr=pthread_create(&tid1,NULL,tfn1,NULL);rnif(err!=0)rnrnprintf("can't create thread %s\n",strerror(err));rnexit(1);rnrnrnrnerr=pthread_join(tid1,NULL);rnif(err!=0)rnrnprintf("can't join thread %s\n",strerror(err));rnexit(1);rnrnrnrnerr=pthread_create(&tid2,NULL,tfn2,NULL);rnif(err!=0)rnrnprintf("can't create thread %s\n",strerror(err));rnexit(1);rnrnrnrnerr=pthread_join(tid2,NULL);rnif(err!=0)rnrnprintf("can't join thread %s\n",strerror(err));rnexit(1);rnrnrnrnerr=pthread_create(&tid3,NULL,tfn3,NULL);rnif(err!=0)rnrnprintf("can't create thread %s\n",strerror(err));rnexit(1);rnrnerr=pthread_cancel(tid3);rnif(err!=0)rnrnprintf("can't cancel thread %s\n",strerror(err));rnexit(1);rnrnrnerr=pthread_join(tid3,NULL);rnif(err!=0)rnrnprintf("can't join thread %s\n",strerror(err));rnexit(1);rnrnrnreturn 0;rnrnrn这段程序执行结果如下:rnthe first threadrnthe second threadrnNO.2 clean up procdurernNO.2 clean up procdurernthe third threadrnNO.2 clean up procdurernready to sleeprnNO.2 clean up procdurern这里我有好几个问题:rn1.在这个函数中,为什么有两个NULL,执行到第一个NULL处,线程已经退出,下面的两个函数(pthread_cleanup_pop(0);rn)怎么会执行到?,如下:rnrnvoid*tfn1(void*arg)rnrnint a=1;rnprintf("the first thread\n");rnpthread_cleanup_push(cleanup,&a);rnrna=2;rnpthread_cleanup_push(cleanup,&a);rnrnreturn NULL;//rnpthread_cleanup_pop(0);rnpthread_cleanup_pop(0);rnrnreturn NULL;//为什么有两个NULL,执行到第一个NULL处,线程已经退出,下面的两个函数(pthread_cleanup_pop(0);rn)怎么会执行到?rnrnrnrn2.执行结果中,出现:rnthe second threadrnNO.2 clean up procdurernNO.2 clean up procdurern为什么不是:rnthe second threadrnNO.2 clean up procdurernNO.1clean up procdurern这个执行结果似乎更合理。rn请高手指教!多谢!

高手进,关于pthread_cleanup_push的问题

12-28

有哪位大侠能整理一下pthread_cleanup_push指定函数不被执行的诸多情况。rnrn目前遇到这样一问题,起一线程,在线程函数最开始加了一个pthread_cleanup_push(freemylock,NULL);在函数结束的地方加了一个pthread_cleanup_pop(0);线程函数又调了其他的函数,用pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);rnpthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);将线程设置成可以取消。此时在线程结束之前我在主线程里pthread_cancel(pthreadid),这时候子线程被中止了,可是我设置的清理函数freemylock()却没被执行。哪位大侠能帮帮我呀,我写的一个测试程序和我实际的程序逻辑是一样的可以执行清理函数,测试程序如下:rn#includern#includern#includernrnvoid inf_lop2()rnrn int w = 0;rn while(++w)rn rn printf("ddddddddddddddddddddddd\n");rn if(w>10000)rn rn break;rn rn rnrnvoid inf_loop()rnrn int i =0;rn while (1)rn rn i++ ;rn inf_lop2();rn// printf("i is %d\n",i);rn// sleep(1);rn// printf("mmmmmmmmmmmmmmmmmmmmmmmm\n");rn rn printf("%d", i);rnrnrnvoid cleanup(void* arg)rn printf("cleanup: wwwwwwwwwwwwwwwwwwwwwwwwwwwwww\n");rnrnrnvoid* thr_fn1(void* arg)rn printf("thread1 starte\n");rn pthread_cleanup_push(cleanup, NULL);rn pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);rn pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);rnrn printf("thread 1 push complete \n");rn while(1)rn rn pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);rnrn printf("11111111111111111111111111\n");rn inf_loop();rn printf("222222222222222222222222222222\n");rn pthread_testcancel();rn printf("33333333333333333333\n");rn rnrn pthread_cleanup_pop(0);rn return ((void*) 1);rnrnrnrnint main(void)rn int err;rn pthread_t tid1, tid2;rn void *tret;rnrn err = pthread_create(&tid1, NULL, thr_fn1, (void*) 1);rnrn getchar();rn printf("thread 1 exit code %d\n", (int)tret);rn pthread_cancel(tid1);rn printf("11111111111\n");rn pthread_join(tid1,NULL);rn printf("qqqqqqqqqqqqq\n");rn sleep(3);rn printf("############################\n");rn printf("thread 2 exit code %d\n", (int)tret);rn getchar();rn return 0;rnrnrnrnrn可在我的工程里就是不执行,到底怎么回事?由于工程太大无法贴出代码望大侠原谅。不知我说明白了没

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭