假设我们有一个多线程C程序(pthreads),并且编译器不会对各个线程的(未同步的)共享变量访问进行重新排序。 x86 CPU是否遵循共享变量访问的顺序(在单个线程内),还是可能重新排序某些内存访问?
答案 0 :(得分:0)
由于存储缓冲区的存在,可能会进行一些重新排序。参见例如https://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf
但是,只有几个线程才能看到重新排序,在一个线程中,来自该线程的所有访问都按顺序发生。
答案 1 :(得分:0)
<击> 非同步的共享变量访问是危险的,并且乱序是它的一个原因 x86按顺序(在一个线程内)保持写入,但不是读取。
如果您认为订单仍然存在,这会让您遇到麻烦。例如:
线程A写入x然后写入y。假设编译器没有重新排序它,cpu将不会重新排序它(x86不会,其他人可能)
线程B读取y然后读取x。你可能会认为,如果它获得了新的价值,那么你肯定也会获得x的新价值
不是这样。 CPU可能会对线程B的读取重新排序,因此实际上会先读取y。
击>
编辑:正如“单向之人”指出的那样,在这种情况下,x86(但不是所有处理器!)保证订购。
我引用英特尔软件开发人员手册:
所有人都以相同的顺序观察单个处理器的写入 处理器。
多个处理器的写入情况并非如此 - 不同的处理器可能会对它们进行不同的排序。
但是,我强烈建议不要依赖它,而是使用正确的同步代替 同步原语使用原子操作和/或障碍实现,这样可以保证您的安全。