linux 信号捕捉和处理的问题~~~在线等

无病呻吟2 2012-12-09 02:59:44
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

/* Simple error handling functions */

#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void * sig_thread(void * arg)
{
printf("pthread_create\n");
sigset_t *sigset = (sigset_t *) arg;
int ret,sig;
for(;;) {
printf("signal_handle_thread\n");
ret = sigwait(sigset,&sig);
if (ret != 0) {
printf("sigwait fail\n");
}
printf("signal handling thread get signal %d\n",sig);
}
return NULL;
}

int signal_block()
{
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGQUIT);
sigaddset(&sigset, SIGUSR1);
sigaddset(&sigset, SIGCHLD);
int ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
if (ret != 0) {
printf("pthread_sigmask error\n");
return -1;
}
pthread_t thread;
ret = pthread_create(&thread,NULL,sig_thread,(void*)&sigset);
if (ret != 0) {
printf("pthread create fail\n");
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
/*
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGQUIT);
sigaddset(&sigset, SIGUSR1);
sigaddset(&sigset, SIGCHLD);
int ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
if (ret != 0) {
printf("pthread_sigmask error\n");
return -1;
}
pthread_t thread;
ret = pthread_create(&thread,NULL,sig_thread,(void*)&sigset);
if (ret != 0) {
printf("pthread create fail\n");
return -1;
}*/

signal_block();
pause(); /* Dummy pause so we can test program */
return 0;
}


上面是可以在linux下直接编译执行的。
上面大段的注释部分和独立函数int signal_block()是一模一样的。
现在问题是:
上面代码编译执行后,在终端上使用kill -USR1 pid / kill -QUIT pid / kill -CHLD pid 有时候无法捕捉相应信号,比较随机。

但是将main函数里上面注释部分解除注释,而将signal_block()这个函数注释,也就是说将signal_block里的功能转移到main函数里逐行逐行来实现,在终端上使用kill -USR1 pid / kill -QUIT pid / kill -CHLD pid ,信号捕获就正常。

请各位高人帮忙解答上述现象的原因,在线等,得到结论马上结单。。。
...全文
122 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zaghost 2012-12-09
  • 打赏
  • 举报
回复
另外,3楼,貌似pthread_sigmask和sigwait是互斥的,要不然信号捕获完全不可能正常。
zaghost 2012-12-09
  • 打赏
  • 举报
回复
2楼正解 如果子进程在signal_block函数返回之前跑到了sigwait的地方,那么有一次机会能捕捉相应信号 signal_block()函数返回后,里面的局部变量就失效了,会产生不可预知的现象 把pause()放到signal_block函数里面似乎也可以解决问题
qq120848369 2012-12-09
  • 打赏
  • 举报
回复
因为主线程屏蔽了这些信号,创建的子线程继承了主线程的信号掩码导致的. 你应该在子线程里先解除那些阻塞信号集, 那么就是你理想的效果了.
慧钦 2012-12-09
  • 打赏
  • 举报
回复
个人看法: pthread_create(&thread,NULL,sig_thread,(void*)&sigset); 这里传入的是signal_block()函数里局部变量的地址,在主函数调用完signal_block()之后,这个局部地址已经不可用了,所以在pause()等待的时间里,由sigset设定的也就不保证是正确的了, 你可以试试用一下static 类型试试..

23,125

社区成员

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

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