Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 信号处理程序中的pthread_exit()_C_Linux_Pthreads - Fatal编程技术网

C 信号处理程序中的pthread_exit()

C 信号处理程序中的pthread_exit(),c,linux,pthreads,C,Linux,Pthreads,(这个问题可能有点相关)我正在编写一个leadlock预防库,其中总是有一个检查线程执行图形操作,并检查是否存在死锁,如果存在死锁,则它会发出一个冲突线程的信号。当该线程捕捉到该信号时,它将释放它拥有的所有互斥锁并退出。有多个资源互斥体(显然)和一个关键区域互斥体,所有获取、释放资源锁和进行图形计算的调用都必须首先获得该锁。现在问题来了。对于两个相互竞争(不包括检查线程)的线程,有时程序会在一个线程被终止后死锁。在gdb中,它表示死线程拥有关键区域锁,但从未释放它。在信号处理程序中添加断点并逐步

(这个问题可能有点相关)我正在编写一个leadlock预防库,其中总是有一个检查线程执行图形操作,并检查是否存在死锁,如果存在死锁,则它会发出一个冲突线程的信号。当该线程捕捉到该信号时,它将释放它拥有的所有互斥锁并退出。有多个资源互斥体(显然)和一个关键区域互斥体,所有获取、释放资源锁和进行图形计算的调用都必须首先获得该锁。现在问题来了。对于两个相互竞争(不包括检查线程)的线程,有时程序会在一个线程被终止后死锁。在gdb中,它表示死线程拥有关键区域锁,但从未释放它。在信号处理程序中添加断点并逐步执行后,锁似乎在pthread_exit()之前属于其他线程(如预期),但在pthread_exit()之后,所有权神奇地转移到了该线程..

我能想到的唯一猜测是,当试图获得关键区域锁(因为它需要另一个资源互斥锁)时,要终止的线程在pthread_mutex_锁处阻塞,然后信号来了,中断了pthread_mutex_锁。因为这个电话不是信号证据,所以发生了奇怪的事情?就像信号处理程序可能已经返回并且线程得到锁然后退出一样?Idk。。任何洞察都将不胜感激

pthread\u exit
不是异步信号安全的,因此,从信号处理程序调用它的唯一方法是确保信号不会中断任何非异步信号安全函数

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

如果您的信号目标只是指示线程终止,那么更好的机制可能是
pthread\u cancel
。但是,为了安全地使用此功能,将被取消的线程必须在适当的点设置取消处理程序,和/或在不安全时临时禁用取消(使用
pthread\u setcancelstate
)。另外,请注意
pthread\u mutex\u lock
不是取消点。没有安全的方法来中断被阻塞的线程等待获取互斥体,因此如果您需要这样的可中断性,您可能需要使用条件变量(condvar waits可取消)进行更精细的同步设置,或者您可以使用信号量而不是互斥体


编辑:如果您真的需要一种方法来终止等待互斥锁的线程,您可以将对
pthread\u mutex\u lock
的调用替换为对您自己的函数的调用,该函数循环调用
pthread\u mutex\u timedlock
并在每次超时时检查退出标志。

谁根据竞争条件锁定定期检查程序?您是否以某种方式获得了一个锁,以防获得任何锁?计时器可以随时执行,信号处理程序可以中断任何内容,包括
pthread\u mutex\u lock
(即使它没有阻塞)。我不知道Linux提供了什么具体措施来解决这个问题,但你可能会提到你做了什么。看看以下链接是否可以帮助你:(1)(2)@Potatoswatter不确定我是否完全理解你的问题,checker只获取cr锁,检查资源图中的周期,如果是这样的话,那么就发出信号,让某人死去,然后再睡1秒钟。这就是它的全部功能。特别是在测试用例中,我有两个线程和两个资源互斥体,竞争条件确实会发生,但更糟糕的情况是,检查器会在1s后发现这一点并杀死一些人。我想我的答案已经涵盖了很多东西,但我用黑体字写的这篇文章对你似乎遇到的问题特别重要:不管你做什么,没有安全的方法来终止正在等待锁定互斥锁的线程。但是信号会中断非异步信号安全函数。@user1095108:如果在调用这些函数时保持信号屏蔽,则不会。但是如果他们中的任何一个被阻挡了,这会破坏信号灯的作用。为什么?该信号的目的可能是中断所述阻塞功能<例如,code>epoll\u wait()。@user1095108:如果您正在中断的是一个安全函数,那么“是”可以正常工作。问题是当它是一个被阻塞的不安全函数时。那么您就不能从处理程序中退出线程了。您能给出一些AS不安全函数的例子吗?此外,信号可能会延迟。因此,在AS不安全函数退出后,它将触发。