免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1952 | 回复: 9
打印 上一主题 下一主题

[系统] 求助!在Linux下用sigaction进行信号处理的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-28 17:56 |只看该作者 |倒序浏览
在Linux编程中遇到一个问题:在使用sigaction进行信号处理的时候,最后的write好像没有被执行,代码如下:
  1. /*
  2. * test the sigaction's sa_mask member
  3. * */

  4. #include "apue.h"

  5. void
  6. signal_handle(int signo)
  7. {
  8.     if(signo == SIGUSR1)
  9.     {
  10.         printf("get signo [SIGUSR1]\n");
  11.         sleep(1);
  12.     }
  13.     else if(signo == SIGUSR2)
  14.     {
  15.         printf("get signo [SIGUSR2]\n");
  16.         sleep(1);
  17.     }
  18. }

  19. int
  20. main(void)
  21. {
  22.     pid_t pid;
  23.     sigset_t set;
  24.     struct sigaction sigac1, sigac2;

  25.     /*sigaction(SIGUSR1, NULL, &sigac1);
  26.     sigaction(SIGUSR2, NULL, &sigac2);*/


  27.     sigfillset(&set);
  28.     sigdelset(&set, SIGUSR1);
  29.     sigdelset(&set, SIGUSR2);
  30.     sigprocmask(SIG_SETMASK, &set, NULL);

  31.     sigac1.sa_handler = signal_handle;
  32.     sigac2.sa_handler = signal_handle;

  33.     /*sigac1.sa_flags |= SA_RESTART;
  34.       sigac2.sa_flags |= SA_RESTART;*/
  35.     sigfillset(&sigac1.sa_mask);
  36.     sigdelset(&sigac1.sa_mask, SIGUSR1);
  37.     sigfillset(&sigac2.sa_mask);
  38.     sigdelset(&sigac2.sa_mask, SIGUSR2);

  39.     if(sigaction(SIGUSR2, &sigac2, NULL) < 0)
  40.         _err("register signal error");
  41.     if(sigaction(SIGUSR1, &sigac1, NULL) < 0)
  42.         _err("register signal error");

  43.     if((pid = fork()) > 0)
  44.     {
  45.         sleep(1);
  46.         kill(pid, SIGUSR1);
  47.         kill(pid, SIGUSR2);
  48.         wait(NULL);
  49.     }
  50.     else
  51.     {
  52.         sleep(1);
  53.         write(STDOUT_FILENO, "hello\n", 6);
  54.     }
  55.     return 0;
  56. }
复制代码
最后的write系统调用没有在终端中输出,不知道是不是系统调用被信号中断了,然后没有重启。但是我使用了如下方式调用sigaction又可以了:
  1. sigaction(SIGUSR1, NULL, &sigac1);
  2.       sigaction(SIGUSR2, NULL, &sigac2);
复制代码
或者使用signal处理信号也可以正常工作。是不是和sigaction中的某写SA_XXXX选项有关?

论坛徽章:
0
2 [报告]
发表于 2013-11-28 21:11 |只看该作者
看一下write的返回值,并且打印一下strerror(errno)看一下呢?

论坛徽章:
0
3 [报告]
发表于 2013-11-28 22:09 |只看该作者
回复 2# pirloofmilan

试过,不行,本来是用printf的,但是考虑到可能是可重入的问题,后来就改成write系统调用了,但问题依旧,会不会信号处理函数没有返回到子进程中,直接就退出了。我用signal或者用sigaction获取了进程中的原先默认的sigaction结构后调用就没问题了。


   

论坛徽章:
0
4 [报告]
发表于 2013-11-29 09:51 |只看该作者
我这测试是可以输出的,printf也可以,区别是我用下面的头文件替换了apue.h
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>

然后_err的调用换成
{
        printf("register SIGUSER1 error: %s\n", strerror(errno));
        return -1;
}

在write之前调用printf("hello by printf\n");

不过hello by printf会输出两次(标准输出是行缓冲)

论坛徽章:
0
5 [报告]
发表于 2013-11-29 11:47 |只看该作者
回复 4# pirloofmilan

我这边的apue.h头文件是自己写的,已经包含了你说的那些头文件。

在我的机子上问题依旧,还是没有输出。

我的环境是Fedora 19/gcc-4.8.1-1,跑在VMware上,你的机器是什么环境的?


   

论坛徽章:
0
6 [报告]
发表于 2013-11-29 12:26 |只看该作者
回复 4# pirloofmilan

我知道问题了,我的sigaction结构变量sigac1和sigac2中的sa_flags成员没有初始化为0,造成在运行的时候这个值是未定义的。


   

论坛徽章:
0
7 [报告]
发表于 2013-11-29 15:45 |只看该作者
回复 6# freshmanrf

好吧,细节



   

论坛徽章:
0
8 [报告]
发表于 2013-11-29 17:18 |只看该作者
回复 7# pirloofmilan

嗯,细节决定成败。


   

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
9 [报告]
发表于 2013-12-01 11:10 |只看该作者
struct sigaction结构体要memset。

论坛徽章:
0
10 [报告]
发表于 2013-12-01 15:19 |只看该作者
回复 9# linux_c_py_php
嗯,用的时候没注意到这个细节。

除了使用memset外,也可以在一开始用sigaction(signum, NULL, &sigac)获取当前进程的默认配置作为初始化值的吧?


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP