C 如果一个线程写入Bool曾经完成,则可以安全地阅读单个线程中的循环中的Bool



我正在构建一个非常简单的程序作为练习。

这个想法是通过在所有内容上递归迭代来计算目录的总大小,并概括目录中包含的所有文件的大小(及其子目录)。

要向用户显示程序仍在工作,此计算是在另一个线程上执行的,而主线程每秒打印一次DOT .

现在,主线程当然需要知道何时应该停止打印点并可以查找结果。可以使用例如std::atomic<bool> done(false);并将其传递给将执行计算的线程,该线程将其完成后将其设置为true。但是我想知道在这种简单的情况下(一个线程一旦完成,一个线程会定期读取直到nonzero)是否有必要为此使用原子数据类型。显然,如果多个线程可能会写入它,则需要保护它。但是在这种情况下,只有一个写作线程和一个阅读线程。

是否有必要在此处使用原子数据类型,还是过度杀伤,可以使用普通数据类型吗?

是的,这是必要的。

问题是处理器的不同核心可以对"相同"数据具有不同的视图,尤其是在CPU中被缓存的数据。atomic零件可确保正确刷新这些缓存,以便您可以安全地执行您的尝试。

否则,另一个线程很可能永远不会从第一个线程看到标志更改。

是的,这是必要的。规则是,如果两个线程可能同时访问相同的内存,而至少一个线程是作者,那么您将有一个数据竞赛。任何具有数据竞赛的程序的执行都具有不确定的行为。

C 14标准的相关报价:

1.10/23

如果程序的执行包含数据竞赛,则它包含两个潜在的并发冲突的动作,其中至少一个不是原子,并且都不发生在另一个情况下,除了下面描述的信号处理程序的特殊情况。任何此类数据竞赛都会导致不确定的行为。

1.10/6

两个表达评估冲突如果其中一个修改了内存位置(1.7),而另一个则访问或修改相同的内存位置。

是的,这是必要的。否则,不能保证在另一个线程中可以观察到一个线程中bool的更改。实际上,如果编译器发现bool变量显然是在设置它的执行线程中再也没有使用过的,则它可能会完全优化设置bool的值的代码。

最新更新