关于sigsetjmp的问题,APUE
本帖最后由 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
pr_mask("starting sig_usr1: "); //(1)
alarm(3);
starttime = time(NULL);
for(;;)
if(time(NULL) > starttime + 5)
break;
pr_mask("finishing sig_usr1: "); //(2)
canjmp = 0;
siglongjmp(jmpbuf, 1);
}
static void
sig_alrm(int signo)
{
pr_mask("in sig_arlm: "); //(3)
}
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 个人看法:
程序设计得好的话完全可以避免使用setjump()/longjump()之类的api
非常熟悉栈,函数调用过程的话就会自然而然地去避免这些导致代码混乱的api 回复 2# garyv
恩,谢谢你的回复。因为我在看Unix环境高级编程这本书,并且个人水平还没有到那个高度,所以只能抄一遍书上的代码,但是结果却大为不同,所以上来求教。 问题解决了,可能是头文件冲突 这...头文件中的函数替代了标准库的函数?{:3_189:} 回复 5# lxyscls
没有,具体情况我也不清楚, "apue.h"头文件里面已经声明了pr_mask函数,并且在别处定义的。而我在自己的代码里面又加了一遍,结果没有输出。
页:
[1]