在信号处理的上下文中,究竟哪个变量需要为sig_atomic_t? [英] Exactly which variables need to be sig_atomic_t in the context of signal handling?

查看:117
本文介绍了在信号处理的上下文中,究竟哪个变量需要为sig_atomic_t?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个使用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.

  1. 没有volatile,编译器可能会将while (!quit) ;优化为无限循环.它找不到修改quit的循环,因此假定quit始终保持为0.
  2. quit的更新或对quit的读取应在单个机器指令中进行.如果需要多条机器指令来更新或读取quit,则如果在进行更新时调用了信号处理程序,则对信号处理程序的读取可能会在quit中看到不一致的值.
  1. Without volatile, the compiler may optimize while (!quit) ; to an infinite loop. It does not find the loop modifying quit, so it assumes that quit always remains 0.
  2. An update to quit or a read of quit should happen in a single machine instruction. If it takes multiple machine instructions to update or read quit, then if a signal handler is invoked while an update was going on, a read in the signal handler may see inconsistent value in quit.

我到目前为止是否正确?如果没有,请在您的回答中纠正我.

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?

c99规范中有2个相关部分:

(§7.14p2)
[sig_atomic_t类型]是对象的(可能是挥发性限定的)整数类型,即使存在异步中断,该对象也可以作为原子实体进行访问

(§7.14 p2)
[The sig_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)
如果信号不是通过调用abortraise的结果出现的,则如果信号处理程序引用了具有静态存储持续时间的任何对象,而不是通过将值分配给声明为,...

(§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 specifier static 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆