volatile用于信号处理程序和多线程

use*_*598 3 c c++ multithreading volatile

据说信号处理程序需要volatile,例如,

volatile int flag = 1; // volatile is needed here?

void run() {
    while(flag) { /* do someting... */ }
}

void signal_handler(int sig) {
    flag = 0;
}

int main() {
    signal(SIGINT, sig_handler);
    run();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

据说volatile通常不用于多线程.但是多线程中类似的情况怎么样:

int flag = 1; // is volatile needed here?

void thread_function() {
    while(flag) { /* do someting... */ }
}

int main() {
    // pthread_create() to create thread_function()...
    sleep(10); // let thread_function run for 10 seconds
    flag = 0;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

两种情况下都应该使用volatile关键字吗?这两种情况是否由编译器以相同的方式处理?

Ker*_* SB 7

允许您从信号处理程序修改的唯一非本地值是类型volatile sig_atomic_t和原子类型.特别是,写你volatile int不是允许的,如果你的信号处理程序运行你不确定的行为.

  • 有用的,如果稍微切向,则添加:虽然在信号处理程序的上下文中不允许你很多,但你可以`write()`到文件描述符.这通常是将"事件"发送到主程序逻辑的最有用的方法.Linux甚至为这种使用模式提供了一个方便的[`signalfd`](http://man7.org/linux/man-pages/man2/signalfd.2.html)API(即代替编写明确转发的信号处理程序该事件,注册一个`signalfd`来读取事件). (2认同)
  • GNU 说:“实际上,你可以假设 int 是原子的。你也可以假设指针类型是原子的;这非常方便。这两个假设在 GNU C 库支持的所有机器上以及所有我们所知道的 POSIX 系统。” https://www.gnu.org/software/libc/manual/html_node/Atomic-Types.html 我认为这意味着可以在信号处理程序中读取/写入“易失性 int”或“易失性 char *”这样的系统。(但根据规范,这仍然是未定义的行为,并且可能会导致其他系统出现问题。) (2认同)