日期:2014-05-16  浏览次数:20927 次

求助sigaction中sa_mask设置阻塞信号的问题!!!
代码经过简化了,只切出来信号的一部分,是用来测试线程池同步的,线程池工作完全正常,没有任何问题!
信号在线程池中的作用也没有任何问题。

在配置SIGINT信号处理过程中,已经在SA_MASK中设置阻塞SIGALRM信号
我的理解是:在sig_intFun函数处理过程中,SIGALRM虽然已经产生,但由于已经设置阻塞SIGALRM信号,
所以sig_alarmFun函数只有在sig_intFun函数调用完了才会被调用。
****************************************************************
所以预期的调用结果是:
---test---
---test---
---test---
通过CTRL+C发送SIGINT信号
--got a sigint--
--sleeping--
--sleeping--
...
--sleeping--
--got a sigalrm--   //在10次SLEEP输出后才输出
*****************************************************************
但是实际的输出是:
---test---
---test---
---test---
通过CTRL+C发送SIGINT信号
--got a sigint--
--sleeping--
--sleeping--
--got a sigalrm--   //alarm发送后,立即捕获SIGALRM信号
...
--sleeping--
  
实际代码中,sig_alarmFun中有线程终止的FLAG,从线程终止的信息来看,sig_intFun在调用时确实没有阻塞SIGALRM

***********************代码**************************
static void sig_alarmFun(int signo)
{
printf("--got a sigalrm--\n");
fflush(stdout);
}

static void sig_intFun(int signo)
{
int i;
printf("--got a sigint--\n");
while(i < 10)
{
printf("--sleeping--\n");
fflush(stdout);
sleep(1);
}
}

int main(int argc, char **argv)
{
struct sigaction act, oact;

act.sa_handler = sig_intFun;
sigemptyset(&act.sa_mask);

//已经设置在SIGINT处理函数期间阻塞SIGALRM信号
sigaddset(&act.sa_mask, SIGALRM);  

act.flags = SA_RESTART | SA_RESETHAND;
sigaction(SIGINT, &act, &oact);

alarm(5);

act.sa_handler = sig_alarmFun;
sigemptyset(&act.sa_mask);
act.flags = SA_RESTART | SA_RESETHAND;
sigaction(SIGALRM, &act, &oact);

while(1)
{
printf("---test---\n");
fflush(stdout);
sleep(1);
}

return 0;
}


求各位大神帮忙分析一下到底是什么原因,为什么理论上sig_intFun调用时理应阻塞SIGALRM,但实际结果却没有呢?先谢谢大家了!

------解决方案--------------------
你是多线程模型下使用信号? 看代码看不出来是多线程

注意只有像alarm这种超时信号会发给引起超时的线程,其他的信号可能会发给进程中任意一个线程