Posted on 2013-01-05 13:46
鑫龙 阅读(1873)
评论(0) 编辑 收藏 引用 所属分类:
本人分析研究
转发请注明出处:http://www.cppblog.com/mysileng/admin/EditPosts.aspx?postid=196971
刚写了程序发现点问题。假设一个程序有多个线程,有一个全局互斥锁M....在某线程A获得锁以后,这个时候来了一个信号(假设这个信号注册了自己的处理程序),那么需要进入信号处理程序,进入以后信号处理处理程序也要获得这个锁。问题来了?会死锁么?
我们知道同一线程如果重复申请同一个互斥锁那么必然会死锁?这里问题转换到信号处理函数跟之前的线程A会是同一个线程上下文么(即是同一个线程么)?我们试验一下。实验之前需要明确几点:
1.根据APUE 12.8,进程的处理函数与处理方式是进程中所有线程共享的。
2.根据APUE 12.8,如果进程接收到信号,该信号只会被递送到某一个单独线程。一般情况下由那个线程引起信号则递送到那个线程。如果没有线程引发信号,信号被发送到任意线程。
上面程序首先共享了一个共同的SIGUSR1信号处理函数,主控线程A然后产生一个线程B,线程B首先获得全局互斥锁,然后运行一个长5秒的程序,然后释放锁。在B运行了大概2秒的时候,线程A给本进程(注意是进程,而不是某线程)发送一个SIGUSR1信号。此时,会死锁么?编译运行看结果.
连续运行了5次,都没有死锁。我们分析一下,当进程接收信号时,进程把信号并没有递送给线程B(因为没有产生死锁),也就是说是不是这个递送过程被优化了?还是我们真的运气好?需要进一步探查。接下来我们指定把信号递送给线程B,看会不会死锁。
接下来编译运行:
不出意料,果然死锁了。
也就是说,关于线程与信号处理函数获得同一把互斥锁的问题,关键是看信号被递送给了那个线程,如果信号是被递送给了获得锁的那个线程,就会死锁,如果不是之前获得锁的线程,程序就继续运行。