这是一个简单的玩具程序,它使用volatile sig_atomic_t
.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#define UNUSED(x) (void) (x)
volatile sig_atomic_t quit;
void sigusr1_handler(int sig)
{
UNUSED(sig);
write(1, "handler\n", 8);
quit = 1;
}
int main()
{
struct sigaction sa;
sa.sa_handler = sigusr1_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
quit = 0;
while (!quit)
;
printf("Exiting ...\n");
return 0;
}
我想我知道为什么这个特定程序中的变量volatile sig_atomic_t
是必要的。quit
- 如果没有
volatile
,编译器可能会优化while (!quit) ;
为无限循环。它没有发现循环正在修改quit
,因此它假定quit
始终保持不变0
。 - 更新
quit
或读取quit
应该发生在单个机器指令中。如果更新或读取需要多条机器指令quit
,那么如果在更新进行时调用信号处理程序,则信号处理程序中的读取可能会在quit
.
到目前为止我是正确的吗?如果没有,请在您的回答中纠正我。
现在我想学习sig_atomic_t
在信号处理的上下文中何时需要的通用规则。Jonathan Leffler 在评论中解释说,提供一个概括并不容易。
您能否提供一个已知场景的列表,其中需要sig_atomic_t
从 C 标准的角度定义变量?它不必是详尽的清单。它可能是经验不足的开发人员在使用信号处理代码编写 C 软件时可以参考的列表。