免费注册 查看新帖 |

Chinaunix

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

[Linux] [结贴]signal()注册的信号处理函数里面,不需要再次注册信号处理函数吗? [复制链接]

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-04-28 18:49 |只看该作者 |倒序浏览
本帖最后由 sentto2 于 2015-04-29 09:31 编辑

网上说,linux下面的signal函数,其实现机制是,在调用信号处理函数之前就会自动把信号处理函数重置,也就是信号处理函数只调用一遍。
如果需要多次都有效的话,信号处理函数里面要再次用signal()注册自身。

但是我写代码测试了一下,发现不用在信号处理函数里面再去注册自己啊,代码如下:

  1. #include<signal.h>
  2. #include<stdio.h>
  3. void f(int sig)
  4. {
  5.   printf("input=%d\n",sig);
  6. }
  7. int main()
  8. {
  9.   signal(SIGHUP,f);
  10.   int i = getchar();
  11.   puts("hello world");
  12.   return 0;
  13. }
复制代码
编译运行g++ ss.cpp&&./a.out
然后在另一个终端里面去不停的发信号:

  1. $ ps -ef|grep a.out
  2. x        27498 27421  0 23:14 pts/3    00:00:00 ./a.out
  3. x        27501 26574  0 23:15 pts/2    00:00:00 grep --color=auto a.out
  4. [x@localhost ~]$ kill -1 27498
  5. [x@localhost ~]$ kill -1 27498
复制代码
那么运行a.out的终端就会不停的输出:

  1. $ g++ ss.cpp&&./a.out
  2. input=1
  3. input=1
复制代码
这是为什么呢? 不是说signal()注册的函数只是一次有效的吗?

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
2 [报告]
发表于 2015-04-28 19:15 |只看该作者
signal注册一次,就可以了啊
  1. #include<signal.h>
  2. #include<stdio.h>
  3. void f(int sig)
  4. {
  5.     printf("input=%d\n",sig);
  6. }
  7. int main()
  8. {
  9.     signal(SIGINT,f);
  10.     while(1)
  11.     {   
  12.         printf("a\n");
  13.         sleep(3);
  14.    
  15.     }   
  16.     return 0;
  17. }
复制代码
你试试这个,每次发生信号,都会触发这个函数,不需要再信号处理函数中重新注册

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
3 [报告]
发表于 2015-04-28 21:11 |只看该作者
zsszss0000 发表于 2015-04-28 19:15
signal注册一次,就可以了啊你试试这个,每次发生信号,都会触发这个函数,不需要再信号处理函数中重新注册


谢谢,我的问题就是这样,你说的不是我想要的: 因为网上总说signal函数注册的处理函数,里面必须再次注册自己才能保证每次都被信号触发。换句话说,signal()函数调用是不是会恢复默认的信号处理函数呢?

谢谢。

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
4 [报告]
发表于 2015-04-28 21:56 |只看该作者
signal的handler不会恢复默认的处理函数回复 3# sentto2


   

论坛徽章:
2
2015年亚洲杯之乌兹别克斯坦
日期:2015-04-15 15:43:482015亚冠之迪拜阿赫利
日期:2015-06-30 20:36:46
5 [报告]
发表于 2015-04-29 17:45 |只看该作者
参考man signal
  1.        In  the  original UNIX systems, when a handler that was established using signal() was invoked by the delivery of a signal, the disposition
  2.        of the signal would be reset to SIG_DFL, and the system did not block delivery of further instances of the signal.  System V also  provides
  3.        these  semantics  for  signal().   This  was bad because the signal might be delivered again before the handler had a chance to reestablish
  4.        itself.  Furthermore, rapid deliveries of the same signal could result in recursive invocations of the handler.

  5.        BSD improved on this situation by changing the semantics of signal handling (but, unfortunately, silently changed the semantics when estab‐
  6.        lishing  a handler with signal()).  On BSD, when a signal handler is invoked, the signal disposition is not reset, and further instances of
  7.        the signal are blocked from being delivered while the handler is executing.

  8.        The situation on Linux is as follows:

  9.        * The kernel's signal() system call provides System V semantics.

  10.        * By default, in glibc 2 and later, the signal() wrapper function does not invoke the kernel system call.  Instead, it  calls  sigaction(2)
  11.          using  flags  that supply BSD semantics.  This default behavior is provided as long as the _BSD_SOURCE feature test macro is defined.  By
  12.          default, _BSD_SOURCE is defined; it is also implicitly defined if one defines _GNU_SOURCE, and can of course be explicitly defined.

  13.          On glibc 2 and later, if the _BSD_SOURCE feature test macro is not defined, then signal() provides  System  V  semantics.   (The  default
  14.          implicit definition of _BSD_SOURCE is not provided if one invokes gcc(1) in one of its standard modes (-std=xxx or -ansi) or defines var‐
  15.          ious other feature test macros such as _POSIX_SOURCE, _XOPEN_SOURCE, or _SVID_SOURCE; see feature_test_macros(7).)

  16.        * The signal() function in Linux libc4 and libc5 provide System V semantics.  If one on a libc5 system includes <bsd/signal.h>  instead  of
  17.          <signal.h>, then signal() provides BSD semantics.
复制代码

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
6 [报告]
发表于 2015-04-29 18:42 |只看该作者
bfdhczw 发表于 2015-04-29 17:45
参考man signal


说的很好,默认编译,signal()调用就是POSIX行为,等同于调用sigaction,会阻塞,没有disposition.
如果编译时加了额外的选项例如-std=c99,那么就是SysV的行为,调用内核的signal。

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP