- 论坛徽章:
- 0
|
研究了一晚上,终于搞明白了,以前看书的时候没仔细想,再次看发现领悟颇多,现解答楼主以及我的疑问。
1,假设执行sigpromask只阻塞一个信号SIGUSR1,
2,然后执行书上说的不希望被SIGUSR!打断的临界区代码。(什么叫临界区,真是难理解)
3,执行完了临界区了。-------------这里的临界区指的就是不希望被某类信号打断的代码段
4,轮到sigsuspend, sigsuspend用othermask替代当前的newmask,并阻塞进程,等待SIGUSR1的到来,为什么要等SIGUSR1?它要一直也不来,进程还不等死在那里?
是得,没信号来的时候进程就是死在那里了,原因是sigsuspend就是要达到这个效果,它就是要让进程暂停,apue上举得这个例子不合适,后面的wait_parent和wait_child就比较合适了。比如wait_parent,这是子进程里的,子进程要让待父进程先执行,所以它要等,但是又不能无限期的等,得有一个信号触发它,告诉它别等了该你执行了。所以这时候子进程需要暂停并等待某一信号,但是这个信号在while之前是被阻塞的,为什么呢,因为子进程在while里面才要进行等待,要是在while之前不阻塞SIGUSR1的话,那在while之前就会触发信号处理函数,就会把flag设置为1,不会再进入while了。所以while里面需要做的是:先把SIGUSR1的阻塞去掉,然后等待此信号的到来,如果我们不用sigsuspend,而用sigprocmask(SIG_SETMASK, &oldmask, NULL) ; pause();的话就会有一个问题,在sigprocmask和pause之间如果有一个SIGUSR1信号,那么它就会触发信号处理函数,触发完之后就会接着执行pause,这时候pause会让程序暂停,这就变成了:sigprocmask解开了对SIGUSR1的阻塞,但是程序还是被暂停了。可以这样来模拟一下:sigprocmask(SIG_SETMASK, &oldmask, NULL) ;sleep(10); pause();这样应该就比较清晰了。
为什么sigsuspend就可以避免这个问题呢?看到大家老说sigsuspend是原子操作,但我一直没搞明白,我看到有人研究明白了,摘录如下:
sigsuspend的整个原子操作过程为:
(1) 设置新的mask阻塞当前进程;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数;
(4) 待信号处理函数返回后,sigsuspend返回。
那么它和sigprocmask() ; pause();有啥区别呢?区别是:sigsuspend把信号捕捉及信号处理函数的调用整合在一起了,也就是说(1)设置新的mask阻塞当前进程后如果有信号我就自己收信号,调用信号处理函数了,而sigprocmask() ; pause();的问题在于它希望在pause之后收信号,而不是sigprocmask() 和pause();之间。
不知道我的解释能不能给大家解惑
6,SIGUSR1来了后,先是恢复newmask,然后执行SIGUSR1的handle,等handle执行完了,sigsuspend也就返回了。
我就是搞不懂,即然临界区都执行完了,也就不怕SIGUSR1了,直接sigpromask(SIG_UNBLOCK,&newmask,&oldmask),解放SIGUSR1,继续往前走也就行了,还弄个叫人搞不懂的sigsuspend原子操作出来干什么?
另外我觉得sigpromask(SIG_UNBLOCK,&newmask,&oldmask)和sigpromask(SIG_SETMASK,&oldmask,NULL),这两个没什么差别,都是恢复原来的阻塞信号集。是我理解错了?
另外,别叫我去看书,书看不懂才来问的 |
|