在下面的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_full
或buffer
。
buffer_full
答案 0 :(得分:3)
我解释你要问一个编译器是否可以通过调用buffer_full
和fill_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
(对于您目前的代码结构)。