线程的取消及清理phread_cleanup_push.docxVIP

  • 50
  • 0
  • 约5.47千字
  • 约 6页
  • 2016-12-02 发布于贵州
  • 举报
线程的取消及清理phread_cleanup_push

取消线程及清理工作知识总结 在多线程编程中,不论是可预见的线程终止还是异常终止,都会存在资源释放的问题,在不考虑因运行出错而退出的前提下,如何保证线程终止时能顺利的 释放掉自己所占用的资源,特别是锁资源,就是一个必须考虑解决的问题。 最经常出现的情形是资源独占锁的使用:线程为了访问临界资源而为其加上锁,但在访问过程中被外界取消,如果线程处于响应取消状态,且采用异步方式响应,或者在打开独占锁以前的运行路径上存在取消点,则该临界资源将永远处于锁定状态得不到释放。外界取消操作是不可预见的,因此的确需要一个机制来 简化用于资源释放的编程。 在POSIX线程API中提供了一个pthread_cleanup_push()/pthread_cleanup_pop()函数对用于自动释放资源--从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用pthread_exit()和取消点终止)都将执行pthread_cleanup_push()所指定的清理函数。 取消线程 一般情况下,线程在其主体函数退出的时候会自动终止,但同时也可以因为接收到另一个线程发来的终止(取消)请求而强制终止。 取消操作允许线程请求终止其所在进程中的任何其他线程。不希望或不需要对一组相关的线程执行进一步操作时,可以选择执行取消操作。例如,用户请求关闭或退出正在运行的应用程序。另一个示例是完成由许多线程执行的任务。其中的某个线程可能最终完成了该任务,而其它线程还在继续运行。由于正在运行的线程此时没有任何用处,因此取消这个线程。 取消点 仅当取消操作安全时才应取消线程。pthreads标准指定了几个取消点,其中包括: 通过pthread_testcancel调用以编程方式建立线程取消点。 线程等待pthread_cond_wait或pthread_cond_timewait()中的特定条件。被sigwait(2)阻塞的函数一些标准的库调用。通常,这些调用包括线程可基于阻塞的函数。缺省情况下,将启用取消功能。有时,您可能希望应用程序禁用取消功能。 如果禁用取消功能,则会导致延迟所有的取消请求,直到再次启用取消请求。 根据POSIX标准,pthread_join()、pthread_testcancel()、pthread_cond_wait ()、pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及read()、 write()等会引起阻塞的系统调用都是Cancelation-point,而其他pthread函数都不会引起Cancelation动作。但是pthread_cancel的手册页声称,由于LinuxThread库与C库结合得不好,因而目前C库函数都不是Cancelation-point; 但CANCEL信号会使线程从阻塞的系统调用中退出,并置EINTR错误码,因此可以在需要作为Cancelation-point的系统调用前后调用pthread_testcancel(),从而达 到POSIX标准所要求的目标,即如下代码段: pthread_testcancel(); retcode = read(fd, buffer, length); pthread_testcancel(); 注意: 程序设计方面的考虑 如果线程处于无限循环中,且循环体内没有执行至取消点的必然路径,则线程无法由外部其他线程的取消请求而终止。因此在这样的循环体的必经路径上应该加入pthread_testcancel()调用。 程序方面的考虑 1. 如果线程处于无限循环中,且循环体内没有执行至取消点的必然路径,则线程无法由外部其他线程的取消请求而终止。因此在这样的循环体的必经路径上应该加入pthread_testcancel()调用。 2. 当pthread_cancel()返回时,线程未必已经取消,可能仅仅将请求发送给目标线程,而目标线程目前没有到达取消点,如果要知道线程在何时中止,就需要在取消它之后调用pthread_join()。有一个例外是当线程被detach后,不能这样处理: ??????a) 当join一个已经detached的线程时,返回EINVAL; ??????b) 如果join后该线程设置为detached,则detach将不起作用。 因此,如果知道一个线程可能会以分离方式运行,就不需要在pthread_cancel()后调用pthread_join()。 放置取消点 执行取消操作存在一定的危险。大多数危险都与完全恢复不变量和释放共享资源有关。取消线程时一定要格外小心,否则可能会使互斥保留为锁定状态,从 而导致死锁状态。或者,已取消的线程可能保

文档评论(0)

1亿VIP精品文档

相关文档