- 论坛徽章:
- 0
|
一开始没看明白APUE里的例子,后来google了下搜索到了这篇文章
http://bigwhite.blogbus.com/logs/1453143.html
它讲:
- 如果按照sig_handler先返回,那么SIGINT是不该被打印出来的,因为那时屏蔽字还没有恢复,所有信号都是不阻塞的。那么是Stevens说错了么?当然没有,只是Stevens没有说请在sigsuspend的原子操作中到底做了什么?
- sigsuspend的整个原子操作过程为:
- (1) 设置新的mask阻塞当前进程;
- (2) 收到信号,恢复原先mask;
- (3) 调用该进程设置的信号处理函数;
- (4) 待信号处理函数返回后,sigsuspend返回。
复制代码
里面(2)说的我看不对啊。
这是APUE里的例子
- #include "apue.h"
- static void sig_int(int);
- int
- main(void)
- {
- sigset_t newmask, oldmask, waitmask;
- pr_mask("program start: ");
- if (signal(SIGINT, sig_int) == SIG_ERR)
- err_sys("signal(SIGINT) error");
- sigemptyset(&waitmask);
- sigaddset(&waitmask, SIGUSR1);
- sigemptyset(&newmask);
- sigaddset(&newmask, SIGINT);
- /*
- * Block SIGINT and save current signal mask.
- */
- if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
- err_sys("SIG_BLOCK error");
- /*
- * Critical region of code.
- */
- pr_mask("in critical region: ");
- /*
- * Pause, allowing all signals except SIGUSR1.
- */
- if (sigsuspend(&waitmask) != -1)
- err_sys("sigsuspend error");
- pr_mask("after return from sigsuspend: ");
- /*
- * Reset signal mask which unblocks SIGINT.
- */
- if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
- err_sys("SIG_SETMASK error");
- /*
- * And continue processing ...
- */
- pr_mask("program exit: ");
- exit(0);
- }
- static void
- sig_int(int signo)
- {
- pr_mask("\nin sig_int: ");
- }
- =================================================
- 打印出
- program start:
- in critical region: SIGINT
- ^C
- in sig_int: SIGINT SIGUSR1
- after return from sigsuspend: SIGINT
- program exit:
复制代码
照它说的顺序,那么in sig_int里不应该有SIGUSR1啊,因为他讲收到信号(这里是SIGINT),就恢复原来mask(就是SIGINT),那么SIGUSR1不应该出现在sig_int里了。
我个人认为:在调用sigsuspend之前只有SIGINT被阻塞,调用sigsuspend后,信号屏蔽字集被临时替换成SIGUSR1,此时可以递送SIGINT,当SIGINT发生,去执行sig_int,注意:在sig_int里会打出in sig_int: SIGINT SIGUSR1 ,是因为操作系统会自动给正在被递送的信号加入屏蔽字集里,当sig_int返回,sigsuspend也将返回,此时屏蔽字就是SIGINT。
由于此文还被到处转载了,个人对sigsuspend用的不是很多,所以有一点浅见,望高人给我看下,该文章是否解释上有点瑕疵。 |
|