是否需要在C中的每次调用中重置信号处理程序?

问题描述 投票:0回答:2

我已阅读以下内容:

当在C程序中调用信号处理程序时,其相应的信号操作将设置为SIG_DFL。如果要再次处理相同的信号,必须重置信号动作。

但是,以下代码在不重置I have received a SIGHUP的情况下仍保持打印状态,不会退回到其默认处理程序。

#include <signal.h> 
#include <stdio.h> 
#include <unistd.h>


void sighup() { 
  //signal(SIGHUP, sighup);
  printf("I have received a SIGHUP\n"); 
} 

int main(){
  signal(SIGHUP, sighup); 
  while(1){
   raise(SIGHUP); 
   sleep(1);
  }
 return 0;
}
c
2个回答
0
投票

您引用的段落仅适用于IBM ILE版本的suggests函数的Google快速搜索signal()

[Linux和BSD上signal的手册页似乎不包含此类声明,并且您已经观察到,似乎没有这种行为。


0
投票

正如其他人提到的,sigaction可能会给您更多控制权。

但是,您不能[不允许]从信号处理程序调用printf。它会弄乱堆和stdout流[或具有其他未指定的效果]。

只能从信号处理程序中调用有限数量的函数,而不会造成灾难性/不可预测的结果[并且printf是其中的[[not其中之一]]]


UPDATE:

抱歉,有关于此的文章吗?信号处理程序与堆有什么关系?

是,请同时参阅man 7 signal和[更重要的是] man 7 signal-safety

printf执行malloc/free以获得[临时]结构。可以在

any

时间调用信号处理程序。如果基本任务位于分配/释放内存的

middle

中,将会发生什么。在线程之间,malloc/free使用互斥量来防止试图同时使用堆的两个线程损坏。但是,当堆处于不确定状态时,互斥锁不会

not

阻止信号处理程序在中间触发。所以,您可能会有:

T0: enter malloc T1: lock mutex T2: start some allocation T3: enter signal handler T4: call printf T5: call malloc T6: change heap T7: exit malloc T8: exit printf T9: exit signal handler T10: try to finish allocation, using stale linked list pointers that are no longer valid -- bang, bang!

© www.soinside.com 2019 - 2024. All rights reserved.