【发布时间】:2017-02-11 23:25:27
【问题描述】:
据说信号处理程序需要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();
// ...
}
据说 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;
// ...
}
在这两种情况下都应该使用 volatile 关键字吗?编译器对这两种情况的处理方式是否相同?
【问题讨论】:
-
volatile[通常] 不足以用于线程间操作(例如锁定、环形队列索引等)。但是,您在这里的用法是用于“运行”标志。只有 1 位作者 (main)。而且,在这两种情况下,它都应该是volatile。在第二种情况下,假设线程函数是while (flag) do_stuff();,main清除flag是一种告诉线程退出循环、进行清理和退出的“温和”方式。您可以将第一个和第二个结合起来,并让信号处理程序为线程清除flag。线程需要pthread_mutex_t等。等等。 -
我会使用
std::atomic_flag(在每个系统上始终是无锁的)或std::atomic_signal_fence。volatile仅强制编译器从指定的内存位置读取和写入,而不是优化值。内存位置也可以只是缓存。 volatile` 不会阻止编译器重新排序您的代码。
标签: c++ c multithreading volatile