如何保证线程终止时能顺利的释放掉自己所占用的资源,特别是锁资源或信号量资源,就是一个必须考虑解决的问题。
为此,系统提供了两个函数。
void pthread_cleanup_push(void (*routine) (void *), void *arg)
void pthread_cleanup_pop(int execute)
从push和pop两个关键字看,这两个函数采用栈管理的方式。
在线程初始执行时,用pthread_cleanup_push()压入清理函数void routine(void *arg),这个函数可以多次执行以压入多个函数形成函数链,而执行的顺序与压入顺序相反。
在线程结束时,用 pthread_cleanup_pop弹出清理函数,参数execute表示弹出清理函数时,是否执行该清理函数。为0表示不执行,为非0表示执行。这个参数不影响异常终止时清理函数的执行,就是说如果程序异常退出,清理函数照常执行。
实例:
仅有一台打印机,要求有新任务到来时即刻停止正在打印的任务,启动新任务
涉及资源独占,使用信号量sem_wait(&avail); 也可以使用pthread_mutex_lock(&mut)来同步。
在主线程中使用pthread_create创建线程,为了主线程不阻塞,使用pthread_detach分离线程。
在子线程中, sem_wait等待获取资源。
使用
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
设置线程可被异步取消。
使用
pthread_cleanup_push(clean_fun,0);
设置清理函数。
在子线程结束处,
pthread_cleanup_pop(0);
弹出处理函数。
在主线程中,可以用sem_trywait判断当前是否有线程在打印。
参考 http://www.cnblogs.com/hnrainll/archive/2011/04/20/2022149.html
http://blog.youkuaiyun.com/caianye/article/details/5912172