免费注册 查看新帖 |

Chinaunix

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

求解signal()函数在接收到第一次信号后还能正常处理之后的信号吗? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-16 10:57 |只看该作者 |倒序浏览
问题以前也遇到过,但一直没怎么弄清楚,这次在学习UNP V2的Posix消息队列时又碰到,不能忍了
要看的主要是mqnotifysignal.c,其余mqcreate.c和mqsend.c在测试时需要,我代码里用的是APUE的头文件,没有的可以把err_sys,err_quit替换成printf,编译时要加上 -lrt 这个链接库,之后可能还要挂载消息队列文件系统 mount -t mqueue none /mnt 。。。

代码如下:

  1. /* mqcreate.c */
  2. #include  <apue.h>
  3. #include  <mqueue.h>

  4. struct mq_attr attr;

  5. int main(int argc, char *argv[])
  6. {
  7.         char c;
  8.         int flags;
  9.         mqd_t mqd;

  10.         flags = O_RDWR | O_CREAT;
  11.         while( (c = getopt(argc, argv, "em:z:")) != -1 )
  12.         {
  13.                 switch ( c )
  14.                 {
  15.                         case 'e' :
  16.                                 flags |= O_EXCL;
  17.                                 break;
  18.                         case 'm' :
  19.                                 attr.mq_maxmsg = atol(optarg);
  20.                                 break;
  21.                         case 'z':
  22.                                 attr.mq_msgsize = atol(optarg);
  23.                                 break;
  24.                         default :
  25.                                 break;
  26.                 }
  27.         }

  28.         if(optind != argc - 1)
  29.                 err_quit("usage: mqcreate [-e] [-m maxmsg -z msgsize] <name>");

  30.         if( (attr.mq_maxmsg != 0 && attr.mq_msgsize == 0) ||
  31.                         (attr.mq_maxmsg == 0 && attr.mq_msgsize != 0))
  32.                 err_quit("must specify both -m maxmsg and -z msgsize");

  33.         if( (mqd = mq_open(argv[optind], flags, FILE_MODE, (attr.mq_maxmsg != 0) ? &attr : NULL)) < 0 )
  34.                 err_sys("mq_open error");

  35.         mq_close(mqd);

  36.         exit(0);
  37. }
复制代码

  1. /* mqsend.c */
  2. #include  <apue.h>
  3. #include  <mqueue.h>

  4. int main(int argc, char *argv[])
  5. {
  6.         mqd_t mqd;
  7.         void *ptr;
  8.         size_t len;
  9.         unsigned int prio;

  10.         if(argc != 4)
  11.                 err_quit("usage: mqsend <name> <#bytes> <priority>");

  12.         len = atoi(argv[2]);
  13.         prio = atoi(argv[3]);

  14.         if( (mqd = mq_open(argv[1], O_WRONLY)) < 0 )
  15.                 err_sys("mq_open error");

  16.         if( (ptr = calloc(len, sizeof(char))) == NULL )
  17.                 err_sys("calloc error");

  18.         if(mq_send(mqd, ptr, len, prio) < 0)
  19.                 err_sys("mq_send error");

  20.         exit(0);
  21. }
复制代码

  1. /* mqnotifysignal.c */
  2. #include  <apue.h>
  3. #include  <mqueue.h>

  4. mqd_t mqd;
  5. void *buff;
  6. struct mq_attr attr;
  7. struct sigevent sigev;

  8. static void sig_usr1(int);

  9. int main(int argc, char *argv[])
  10. {
  11.         if(argc != 2)
  12.                 err_quit("usage: mqnotifysignal <name>");

  13.         if( (mqd = mq_open(argv[1], O_RDONLY)) < 0 )
  14.                 err_sys("mq_open error");
  15.         if( mq_getattr(mqd, &attr) < 0 )
  16.                 err_sys("mq_getattr error");
  17.         if( (buff = malloc(attr.mq_msgsize)) == NULL )
  18.                 err_sys("malloc error");

  19.         if( signal(SIGUSR1, sig_usr1) < 0 )
  20.                 err_sys("signal error");
  21.         sigev.sigev_notify = SIGEV_SIGNAL;
  22.         sigev.sigev_signo = SIGUSR1;
  23.         if( mq_notify(mqd, &sigev) < 0 )
  24.                 err_sys("mq_notify error");

  25.         while(1)
  26.                 pause();

  27.         exit(0);
  28. }

  29. static void sig_usr1(int signo)
  30. {
  31.         ssize_t n;

  32.         if( mq_notify(mqd, &sigev) < 0 )
  33.                 err_sys("mq_notify error");

  34.         if( (n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) < 0 )
  35.                 err_sys("mq_receive error");
  36.         printf("SIGUSR1 received, read %ld bytes\n", (long)n);

  37.         return;
  38. }
复制代码
测试结果是:
./mqcreate -m 10 -z 8192 /test
./mqnotifysignal /test1
现在在另一个控制台下:
./mqsend /test1 100 50   (正常,显示 “SIGUSR1 received, read 100 bytes”)
./mqsend /test1 100 50   (第二次就不正常了,显示 “User defined signal 1”)

现在如果把signal函数移动到while循环下,就可以正常每次都接收到消息,求解啊!
  1. while(1)
  2.         {
  3.                 if( signal(SIGUSR1, sig_usr1) < 0 )
  4.                         err_sys("signal error");
  5.                 pause();
  6.         }
复制代码

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2011-10-16 11:22 |只看该作者
回复 1# nick_lhy


    signal() 現在就不要再用了,用 sigaction() 吧。你的問題,看看 signal() 的手冊就清楚了。

论坛徽章:
0
3 [报告]
发表于 2011-10-16 14:10 |只看该作者
回复 2# MMMIX


   好吧,以后都得用sigaction了看来

论坛徽章:
0
4 [报告]
发表于 2011-12-06 11:39 |只看该作者
APUE 里面也有说,signal处理信号后,需要在信号处理函数中重新安装处理程序。用sigaction好。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP