volatile for signal handler and multi-threading

∥☆過路亽.° 提交于 2020-03-02 06:28:07

问题


It is said volatile is needed for signal handler, e.g.,

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();
    // ...
}

It is said volatile is often not used in multithreading. But how about the similar case like above in multithreading:

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;
    // ...
}

Should the volatile keyword be used in both cases? Are the two cases treated the same way by compiler?


回答1:


volatile is used to make sure that the contents of the variable is read from the actual memory rather than from a CPU register.

In other words, whenever an "outside" event might change the value of a variable, you should consider using volatile ("outside" - as in, outside the relevant code block).

In both your examples, you are using the variable as a flag to signal a change in behavior. This flag, in both examples, is controlled by events "outside" the loop that that is reviewing the flag. For this reason, both examples require the use of the volatile keyword.

It should be noted volatile does not provide thread safety for a number of reasons. To make sure an object is thread safe, read/write operations must be either protected or atomic.




回答2:


The only non-local values you are allowed to modify from a signal handler are those of type volatile sig_atomic_t, and atomic types. In particular, writing to your volatile int is not allowed, and if your signal handler runs you have undefined behaviour.




回答3:


The c++ standard, in [intro.execution], paragraph 6, tells:

When the processing of the abstract machine is interrupted by receipt of a signal, the values of objects which are neither
— of type volatile std::sig_atomic_t nor
— lock-free atomic objects (29.4)
are unspecified during the execution of the signal handler, and the value of any object not in either of these two categories that is modified by the handler becomes undefined.

Therefore, yes, for signal handlers, you have to use volatile std::sig_atomic_t.



来源:https://stackoverflow.com/questions/42182435/volatile-for-signal-handler-and-multi-threading

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!