我需要记忆障碍吗?

时间:2016-08-29 15:03:19

标签: c multithreading thread-safety memory-barriers

在下面的C99示例中,在读取或写入缓冲区后,是否保证设置private final String POSTGRES_DIR = "C:\\Program Files\\PostgreSQL\\9.3\\bin\\" private final String POSTGRES_COMMAND = "psql.exe"; .... ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", command).directory(new File(POSTGRES_DIR)); ..... 标志(即使启用了-O2优化)?或者,我是否需要内存屏障以确保正确排序?

我希望这可以在一个对齐的32位读写是原子的系统上运行。

假设每个线程只运行一个实例,其他线程没有访问buffer_fullbuffer

buffer_full

1 个答案:

答案 0 :(得分:3)

我解释你要问一个编译器是否可以通过调用buffer_fullfill_buffer()将作业重新排序到read_buffer()。只有在不改变程序的外部可观察行为的情况下,才允许这样的优化(和任何优化)。

在这种情况下,由于buffer_full具有外部链接,因此编译器不太可能确信是否允许优化。如果fill_buffer()use_buffer()函数的定义以及它们自己调用的每个函数的定义,它可能会这样做。与writer_thread()reader_thread()函数位于同一个翻译单元中,但这在某种程度上取决于它们的实现。如果符合标准的编译器不确定允许优化,那么它就不能执行它。

因为您的命名意味着这两个函数将在不同的线程中运行,然而,如果没有内存屏障等同步操作,您就无法确定一个线程感知修改由不同线程执行的共享,非_Atomic,非volatile数据。

此外,如果一个线程写入非原子变量而另一个线程访问同一个变量(读取或写入),那么除非同步操作或原子操作在每个可能的整体顺序中介入,否则存在数据争用的运作。 volatile个变量在这里并没有真正帮助(参见Why is volatile not considered useful in multithreaded C or C++ programming?)。但是,如果你使buffer_full为原子,或者如果你使用原子读写操作来实现你的函数,那么这将有助于避免数据争用不仅涉及该变量,而且还涉及buffer(对于您目前的代码结构)。