在信号处理的上下文中,究竟哪个变量需要为sig_atomic_t? [英] Exactly which variables need to be sig_atomic_t in the context of signal handling?
问题描述
这是一个使用volatile sig_atomic_t
的简单玩具程序.
Here is a simple toy program that uses 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
变量是必需的.
I think I know why volatile sig_atomic_t
is necessary for the quit
variable in this particular program.
- 没有
volatile
,编译器可能会将while (!quit) ;
优化为无限循环.它找不到修改quit
的循环,因此假定quit
始终保持为0
. - 对
quit
的更新或对quit
的读取应在单个机器指令中进行.如果需要多条机器指令来更新或读取quit
,则如果在进行更新时调用了信号处理程序,则对信号处理程序的读取可能会在quit
中看到不一致的值.
- Without
volatile
, the compiler may optimizewhile (!quit) ;
to an infinite loop. It does not find the loop modifyingquit
, so it assumes thatquit
always remains0
. - An update to
quit
or a read ofquit
should happen in a single machine instruction. If it takes multiple machine instructions to update or readquit
, then if a signal handler is invoked while an update was going on, a read in the signal handler may see inconsistent value inquit
.
我到目前为止是否正确?如果没有,请在您的回答中纠正我.
Am I correct so far? If not, please correct me in your answer.
现在,我想学习一个通用的规则,以了解在信号处理方面何时需要sig_atomic_t
的情况.乔纳森·莱夫勒(Jonathan Leffler)在评论中解释说,提供一个概括并不容易.
Now I want to learn a generalized rule for when sig_atomic_t
is necessary in the context of signal handling. Jonathan Leffler has explained in the comment that it is not easy to provide a generalization.
您能否提供从C标准角度来看需要将变量定义为sig_atomic_t
的已知方案的列表?它不必是详尽的清单.可能是经验不足的开发人员在编写带有信号处理代码的C软件时可以参考的列表.
Can you provide a list of known scenarios where a variable needs to be defined as sig_atomic_t
from C standard perspective? It need not be an exhaustive list. It could be a list a less experienced developer can refer to while writing C software with signal handling code.
推荐答案
您能否提供从C标准角度需要将变量定义为
sig_atomic_t
的已知方案的列表?
Can you provide a list of known scenarios where a variable needs to be defined as
sig_atomic_t
from C standard perspective?
(§7.14p2)
[sig_atomic_t
类型]是对象的(可能是挥发性限定的)整数类型,即使存在异步中断,该对象也可以作为原子实体进行访问
(§7.14 p2)
[Thesig_atomic_t
type] is the (possibly volatile-qualified) integer type of an object that can be accessed as an atomic entity, even in the presence of asynchronous interrupts
(§7.14.1.1p5)
如果信号不是通过调用abort
或raise
的结果出现的,则如果信号处理程序引用了具有静态存储持续时间的任何对象,而不是通过将值分配给声明为
(§7.14.1.1 p5)
If the signal occurs other than as the result of calling the abort
or raise
function, the behavior is undefined if the signal handler refers to any object with static storage duration other than by assigning a value to an object declared as volatile sig_atomic_t
, ...
静态存储持续时间"定义为:
"Static storage duration" is defined as:
(§6.2.4p3)
通过外部或内部链接或存储类说明符static
声明其标识符的对象具有静态存储持续时间.它的生命周期是程序的整个执行过程,并且在程序启动之前,其存储值仅初始化一次.
(§6.2.4 p3)
An object whose identifier is declared with external or internal linkage, or with the storage-class specifierstatic
has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
简而言之,如果可以异步访问变量(即在信号处理程序的内部和外部都访问变量),则需要使用volatile sig_atomic_t
.此外,访问具有静态存储持续时间的非volatile sig_atomic_t
变量是未定义的行为.未定义的行为意味着,不仅变量值不一致,程序还可以完全执行其他操作(例如segfault).
In a nutshell, you are required to use volatile sig_atomic_t
if the variable may be accessed asynchronously (i.e., the variable is accessed both inside and outside of the signal handler). In addition, it is undefined behavior to access a non-volatile sig_atomic_t
variable which has static storage duration. Undefined behavior means that not only could the value of the variable be inconsistent, the program could do something else entirely (like segfault).
这篇关于在信号处理的上下文中,究竟哪个变量需要为sig_atomic_t?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!