信号处理程序中的pthread_exit()

(这个问题可能与信号处理程序中的pthread_exit有些相关导致分段错误 )我正在编写一个引导锁定防止库,其中总是有一个检查线程正在执行图形内容并检查是否存在死锁,如果有,则它会发出其中一个信号冲突的线程。 当该线程捕获信号时,它释放它拥有并退出的所有互斥锁。 有多个资源互斥(显然)和一个关键区域互斥,所有获取,释放资源锁定和执行图形计算的调用必须首先获得此锁定。 现在出现了问题。 使用2个竞争(不计入检查线程)线程, 有时程序在一个线程被杀死后死锁。 在gdb中,它说死线程拥有关键区域锁定但从未释放它。 在信号处理程序中添加断点并单步执行后, 在pthread_exit()之前看起来锁属于其他人(正如预期的那样),但是在pthread_exit()之后,所有权神奇地转到了这个线程。

我能想到的唯一猜测是,当试图获得关键区域锁定时,被杀死的线程在pthread_mutex_lock处阻塞(因为它需要另一个资源互斥锁),然后信号来了,中断了pthread_mutex_lock。 由于这个电话不是信号防范的,所以发生了一些奇怪的事情? 就像信号处理程序可能已经返回并且该线程获得锁定然后退出? Idk ..感谢任何见解!

pthread_exit不是异步信号安全的,因此你可以从信号处理程序调用它的唯一方法是确保信号不会中断任何非异步信号安全function。

作为一般原则,使用信号作为与线程通信的方法通常是一个非常糟糕的主意。 您最终会混淆两个本身已经足够困难的问题:线程安全(线程之间的正确同步)和单个线程内的重入。

如果您的信号目标只是指示线程终止,那么更好的机制可能是pthread_cancel 。 但是,要安全地使用它,将被取消的线程必须在适当的位置设置取消处理程序和/或在不安全时暂时禁用取消(使用pthread_setcancelstate )。 另外,请注意pthread_mutex_lock不是取消点。 没有安全的方法来中断被阻塞等待获取互斥锁的线程,所以如果你需要这样的可中断性,你可能需要更复杂的条件变量同步设置(condvar等待是可取消的),或者你可以使用信号量而不是信号量互斥。

编辑:如果你确实需要一种方法来终止等待互斥锁的线程,你可以用调用你自己的函数替换对pthread_mutex_lock的调用,该函数循环调用pthread_mutex_timedlock并在每次超时时检查退出标志。