- 论坛徽章:
- 1
|
本帖最后由 suanmeilizhi 于 2011-12-30 13:40 编辑
程序结构是这样的,在main中首先打印当前信号屏蔽字(pr_mask的作用),然后保存当前环境,等待信号,进程收到信号之后,执行sig_usr1函数,当前的信号被自动加入到信号屏蔽字,所以再次打印的时候应该能看到SIGUSR1(而实际却没有),在信号处理函数sig_usr1中再处理SIGALRM的信号处理函数,同样打印信号屏蔽字,此时的内容应该为SIGUSR1和SIGALRM,然后依次返回,最后在main中,信号屏蔽字应该为空了,但是程序执行时没有任何实际输出。
上代码:- #include "apue.h"
- #include <unistd.h>
- #include <setjmp.h>
- #include <time.h>
- #include <errno.h>
- static void sig_usr1(int), sig_alrm(int);
- static sigjmp_buf jmpbuf;
- static volatile sig_atomic_t canjmp;
- int
- main(void)
- {
- if(signal(SIGUSR1, sig_usr1) == SIG_ERR)
- err_sys("signal(SIGUSR1) error");
- if(signal(SIGALRM, sig_alrm) == SIG_ERR)
- err_sys("signal(SIGALRM) error");
- //打印当前被屏蔽的信号
- pr_mask("Starting main: ");
- if(sigsetjmp(jmpbuf, 1)) {
- pr_mask("End main: ");
- exit(0);
- }
- canjmp = 1; //保证sigsetjmp完成之前不会调用siglongjmp
- raise(SIGUSR1);
- }
- static void
- sig_usr1(int signo)
- {
- time_t starttime;
- if(canjmp == 0) {
- return;
- }
- //当前信号被自动加入到进程的信号屏蔽字中,所以此处应该打印 starting sig_usr1: SIGUSR1
- [color=Red]pr_mask("starting sig_usr1: "); //(1)[/color]
- alarm(3);
- starttime = time(NULL);
- for(;;)
- if(time(NULL) > starttime + 5)
- break;
- [color=Red]pr_mask("finishing sig_usr1: "); //(2)[/color]
- canjmp = 0;
- siglongjmp(jmpbuf, 1);
- }
- static void
- sig_alrm(int signo)
- {
- [color=Red]pr_mask("in sig_arlm: "); //(3)[/color]
- }
- void
- pr_mask(const char *str)
- {
- sigset_t sigset;
- int errno_save;
- errno_save = errno;
- if (sigprocmask(0, NULL, &sigset) < 0)
- err_sys("sigprocmask error");
- printf("%s", str);
- if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
- if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
- printf("\n");
- errno = errno_save;
- }
复制代码 在代码中标出了(1)(2)(3),这三处都应该有打印结果,但是实际结果确实这样:- $ ./a.out
- Starting main:
- starting sig_usr1:
- in sig_arlm:
- finishing sig_usr1:
- End main:
复制代码 按书照抄一遍也有错,不知道为什么???
环境:
Linux ubuntu 2.6.32-34-generic #77-Ubuntu SMP Tue Sep 13 19:40:53 UTC 2011 i686 GNU/Linux |
|