我已阅读以下内容:
当在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;
}
您引用的段落仅适用于IBM ILE版本的suggests函数的Google快速搜索signal()
。
[Linux和BSD上signal
的手册页似乎不包含此类声明,并且您已经观察到,似乎没有这种行为。
正如其他人提到的,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!