正确的是,已取消线程不会解锁它们所持有的互斥锁,您需要手动安排该操作,这很棘手,因为您需要非常小心地在每个可能的取消点周围使用正确的清除处理程序。假设您
pthread_cancel用于取消线程并设置清除处理程序
pthread_cleanup_push以解锁互斥锁,则可以尝试以下两种替代方法,它们可能更容易正确使用,因此可能更可靠。
使用RAII解锁互斥锁
会 更可靠。在GNU / Linux
pthread_cancel上,使用type的特殊异常来实现
__cxxabi::__forced_unwind,因此,取消线程时,将引发异常并取消堆栈堆栈。如果一个互斥锁被RAII类型锁定,那么如果堆栈被
__forced_unwind异常取消,则可以保证其析构函数运行。
Boost Thread提供了一个可移植的C
++库,该库包装了Pthreads,并且使用起来更加容易。它提供了RAII类型
boost::mutex和其他有用的抽象。Boost
Thread还提供了自己的“线程中断”机制,该机制类似于Pthread取消,但不相同,并且提供了Pthread取消点(例如
connect)不是Boost
Thread中断点,这对某些应用程序可能会有帮助。但是,对于您的客户而言,由于取消的目的是中断
connect调用,因此他们可能确实希望坚持使用Pthread取消。GNU
/ Linux(非便携式)实现取消的方式是一种例外,这意味着它将与配合使用
boost::mutex。
在用C 编写时,确实没有任何借口显式锁定和解锁互斥锁。恕我直言,C 最重要和最有用的 功能是析构函数,它是自动释放互斥锁等资源的理想选择。
另一种选择是使用一个强大的互斥体,它是通过调用创建
pthread_mutexattr_setrobust一个
pthread_mutexattr_t初始化互斥之前。如果线程在持有健壮的互斥锁时死亡,内核将对其进行记录,以便下一个试图锁定互斥锁的线程获得特殊的错误代码
EOWNERDEAD。如果可能,新线程可以使该线程保护的数据再次保持一致,并获得互斥锁的所有权。与仅使用RAII类型锁定和解锁互斥锁相比,要正确使用它要困难得多。
完全不同的方法是确定在调用时是否真的需要按住互斥锁
connect。在慢速操作期间保持互斥不是一个好主意。
connect如果成功锁定了互斥锁并更新了互斥锁正在保护的任何共享数据,那么您不能打电话吗?
我的首选是同时使用Boost Thread和避免长时间保持互斥。



