为什么 sigsuspend 在 while 循环中不起作用?
Why sigsuspend does not work in while loop?
我正在尝试了解信号的工作原理。当我将 sigsuspend 放在 while 循环之外时,代码有效,否则无效。为什么?
static void signal_handler(int sig) {
printf("SIGUSR1 has been received!");
}
int main() {
struct sigaction sigact;
sigset_t sigset;
sigemptyset(&sigset);
sigact.sa_handler = signal_handler;
sigact.sa_mask = sigset;
sigact.sa_flags = 0;
sigaction(SIGUSR1, &sigact, NULL);
while(1) {
sigsuspend(&sigset);
printf("The signal has been received!");
}
}
When i put sigsuspend outside of the while loop the code works otherwise it doesn't.
我的意思是,当您将 SIGUSR1 发送到根据所提供的代码构建的程序时,您看不到任何输出。这与循环或信号没有直接关系。问题是标准输出在默认情况下是 buffered —— 当它连接到终端时行缓冲,否则完全缓冲。如果您向进程发送足够多的 SIGUSR1,它最终会打印足够多的输出来填充缓冲区,然后您将看到所有消息。
要立即查看消息,
(如果 stdout 连接到终端)在每条消息的末尾添加一个换行符:
printf("The signal has been received!\n");
或
在每个 printf
:
之后刷新标准输出
printf("The signal has been received!");
fflush(stdout);
或
改为将输出定向到 stderr,默认情况下是无缓冲的:
fprintf(stderr, "The signal has been received!");
甚至
更改标准输出的缓冲模式:
setvbuf(stdout, NULL, _IONBF, 0);
(一次就够了)
至于为什么你认为当你只调用一次 sigsuspend()
而不是无限循环时你会看到不同的行为,那是因为当程序正常终止时,程序打开的流会自动刷新和关闭。
此外,printf()
不是 async-signal-safe,因此您可以通过从信号处理程序调用它来引发未定义的行为。不要那样做,即使它在某些情况下似乎对你有用。
我正在尝试了解信号的工作原理。当我将 sigsuspend 放在 while 循环之外时,代码有效,否则无效。为什么?
static void signal_handler(int sig) {
printf("SIGUSR1 has been received!");
}
int main() {
struct sigaction sigact;
sigset_t sigset;
sigemptyset(&sigset);
sigact.sa_handler = signal_handler;
sigact.sa_mask = sigset;
sigact.sa_flags = 0;
sigaction(SIGUSR1, &sigact, NULL);
while(1) {
sigsuspend(&sigset);
printf("The signal has been received!");
}
}
When i put sigsuspend outside of the while loop the code works otherwise it doesn't.
我的意思是,当您将 SIGUSR1 发送到根据所提供的代码构建的程序时,您看不到任何输出。这与循环或信号没有直接关系。问题是标准输出在默认情况下是 buffered —— 当它连接到终端时行缓冲,否则完全缓冲。如果您向进程发送足够多的 SIGUSR1,它最终会打印足够多的输出来填充缓冲区,然后您将看到所有消息。
要立即查看消息,
(如果 stdout 连接到终端)在每条消息的末尾添加一个换行符:
printf("The signal has been received!\n");
或
在每个
之后刷新标准输出printf
:printf("The signal has been received!"); fflush(stdout);
或
改为将输出定向到 stderr,默认情况下是无缓冲的:
fprintf(stderr, "The signal has been received!");
甚至
更改标准输出的缓冲模式:
setvbuf(stdout, NULL, _IONBF, 0);
(一次就够了)
至于为什么你认为当你只调用一次 sigsuspend()
而不是无限循环时你会看到不同的行为,那是因为当程序正常终止时,程序打开的流会自动刷新和关闭。
此外,printf()
不是 async-signal-safe,因此您可以通过从信号处理程序调用它来引发未定义的行为。不要那样做,即使它在某些情况下似乎对你有用。