【发布时间】:2015-07-08 06:45:42
【问题描述】:
我正在使用 signal.h 和 unistd.h 库,但遇到了一些问题。在下面的代码中,当我通过调用CTRL-C 将SIGINT 信号发送到正在运行的程序时,该信号被捕获。但是,当再次按下CTRL-C 时,程序会终止。据我了解,每次按CTRL-C时都应该打印打印语句"Received signal 2"。
是我对这个信号的理解不正确,还是我的代码有错误?
感谢您的意见!
#include "handle_signals.h"
void sig_handler(int signum)
{
printf("\nReceived signal %d\n", signum);
}
int main()
{
signal(SIGINT, sig_handler);
while(1)
{
sleep(1);
}
return 0;
}
终端输出:
xxx@ubuntu:~/Dropbox/xxx/handle_signals$ ./handle_signals
^C
Received signal 2
^C
xxx@ubuntu:~/Dropbox/xxx/handle_signals$
编辑:这是我包含的标题
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void sig_handler(int signum);
感谢您的回复。现在通读一遍!
【问题讨论】:
-
你没有“发送 ctrl+c”,你按那个。然后发生的事情是按键被解释为将 SIGINT 发送到您的进程。不能保证您的 shell 不会认为“嗯,连续两个 ctrl+c,最好发送 SIGKILL”之类的。尝试使用
killall -SIGINT yourprogram,看看效果是否更好。 -
它在我的系统上运行良好。您的文件
handle_signals.h中有什么内容?另请注意,严格来说,信号处理程序不应调用像printf这样的其他系统函数,它应该只设置一些标志变量左右。 -
@Marian:不仅严格来说,在信号处理程序中做大量 IO 绝不是一个好主意。但是,
printf不是一个系统函数(它是一个 libc 函数),而是一个内部调用write并且可能调用fdatasync的函数。有关允许的系统调用的参考,请运行man 7 signal;write和fdatasync允许在信号处理程序中使用。这并不意味着这是一个好主意——信号基本上可能会在执行过程中随处发生,即使只是有一些东西要刷新到标准输出,所以你会得到信号处理程序和常规输出的完美结合。 -
@MarcusMüllerꕺꕺ:实际上可以保证 shell 不会那样做:shell 甚至看不到 Ctrl+C(这一切都由内核中的终端驱动程序代码处理)。
-
@MarcusMüllerꕺꕺ
printf(3)不是异步信号安全的。它可能出于各种原因调用malloc(3)或free(3)- 例如,初始化标准I/O 库内部使用的缓冲区。它不应该在信号处理程序中使用。