Chinaunix
标题:
linux下 信号多次触发无效问题?
[打印本页]
作者:
lemon627
时间:
2010-12-03 14:36
标题:
linux下 信号多次触发无效问题?
本帖最后由 lemon627 于 2010-12-03 15:30 编辑
我是在RedHat linux 5 as下,
信号SIGUSR2能触发第一次信号,之后就不行了,不知道为什么?哪位高手看看?
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf have_recv_env;
char have_recv_flag = 0;
have_recv()
{
alarm(0);
have_recv_flag = 1;
fprintf(stderr, "Recv a signal SIGUSR2, have_recv.(pid:%d)\n", getpid());
longjmp(have_recv_env, 1);
}
void main()
{
int i=0;
int j=1;
signal(SIGUSR2, SIG_IGN);
fprintf(stderr, "start test(pid:%d)\n", getpid());
while(1)
{
fprintf(stderr, "==========================\n");
fprintf(stderr, "begin while times(%d)\n", j);
have_recv_flag = 0;
i=signal(SIGUSR2, (void (*)())have_recv);
fprintf(stderr, "signal have_recv :i=[%d]\n", i);
setjmp(have_recv_env);
fprintf(stderr, "setjmp(have_recv_env)\n");
if (have_recv_flag == 1) {
signal(SIGUSR2, SIG_IGN);
fprintf(stderr, "recv SIGUSR2\n");
}
else
pause();
j++;
fprintf(stderr, "end while\n");;
}
;
}
复制代码
作者:
sudoers
时间:
2010-12-03 16:38
问题出在你使用 setjmp 和 longjmp上。
首先说下信号处理过程中一般流程:
1. 收到SIGUSR2信号
2. 进入信号处理函数,此时,SIGUSR2自动被加入到进程信号屏蔽字
3. 执行信号处理任务
4. 处理完成后,恢复信号屏蔽字,即SIGUSR2会取消阻塞
5. 返回到中断现场
你程序的问题:
在进入你的信号处理程序以后,前面流程的前 3 步都能正常完成,但是系统没能做 4 的工作你就 longjmp 出去了,
也就是导致没有把进程的信号屏蔽字恢复, SIGUSR2也就是处于阻塞状态,你当然就不可能接收到信号了。
解决办法:
系统信号处理库有提供 sigsetjmp, 和 siglongjmp 专门用于处理从信号处理函数中跳转,用这两个 api 就能解决问题。
作者:
lemon627
时间:
2010-12-06 15:19
受教,非常感谢,问题解决了{:3_190:}
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2