sigprocmask函数对不再阻塞信号的返回问题

bingyaoming 2007-12-21 11:07:27
<<UNIX环境高级编程>>上说:如果在调用s i g p r o c m a s k后有任何未决的、不再阻塞的信号,则在s i g p r o c m a s k返回前,至少将其中之一递送给该进程。

小弟用下列程序对这句话进行测试:先屏蔽掉SIGUSR1和SIGUSR2信号,然后用kill函数发送他们,再打开它们.
可运行结果却是:
SIGUSR is blocked
SIGUSR1 function
SIGUSR2 function
SIGUSR1 function
SIGUSR is unblocked

为什么会返回两次SIGUSR1函数呢?谢谢回答

程序如下:
#include <stdlib.h>
#include <signal.h>
static void sig_usr1(signo)
{
printf("SIGUSR1 function\n");
}
static void sig_usr2(signo)
{
printf("SIGUSR2 function\n");
}
main()
{
sigset_t newmask,oldmask;
if(signal(SIGUSR1,sig_usr1)<0|signal(SIGUSR2,sig_usr2)<0)
perror("signal\n");
sigemptyset(&newmask);
sigaddset(&newmask,SIGUSR1);
sigaddset(&newmask,SIGUSR2);
sigprocmask(SIG_BLOCK,&newmask,&oldmask);
printf("SIGUSR is blocked\n");
kill(getpid(),SIGUSR2);
kill(getpid(),SIGUSR1);

sigprocmask(SIG_SETMASK,&oldmask,NULL);
}
...全文
125 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
bingyaoming 2007-12-25
  • 打赏
  • 举报
回复
太感谢您了
cceczjxy 2007-12-21
  • 打赏
  • 举报
回复
signal是不可靠信号函数,有个"时间窗",漏洞.
具体过程是这样的:

当调用sigprocmask函数放开信号屏蔽后,系统会按循序检查悬挂的的信号,注意,这个顺序不是信号到来的顺序,而是信号值的顺序,即1-64;
当检查到sigusr1时发现有信号,进入sigusr1的信号句柄,内核为这个句柄函数在用户空间建立函数栈,因为信号句柄函数在用户空间,所有当执行时可以被打断,进入sigusr2句柄函数,执行完后,清除sigusr2信号悬挂标志,再检查信号悬挂情况,发现sigusr1信号悬挂标志还有,就再为其建立先后句柄,执行,执行完后.清除标志,再接着,回到用户空间,按正常的函数情况执行,发现有函数栈没有执行,就再执行.



用sigaction设置函数句柄就没问题了.
struct sigaction act1,act2;
act1.sa_handler=sig_usr1;
sigemptyset(&act1.sa_mask);
act2.sa_handler=sig_usr2;
sigemptyset(&act2.sa_mask);
sigaction(SIGUSR1,&act1,NULL);
sigaction(SIGUSR2,&act2,NULL);


我在这个问题上也有点糊涂,sigusr1虽然执行了两遍,但好象执行的是同一个栈.没仔细研究过.上述意见仅供参考.
bingyaoming 2007-12-21
  • 打赏
  • 举报
回复
自己顶一下

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧