多线程和乱序执行

时间:2011-12-21 14:08:00

标签: multithreading x86 shared-memory

假设我们有一个多线程C程序(pthreads),并且编译器不会对各个线程的(未同步的)共享变量访问进行重新排序。 x86 CPU是否遵循共享变量访问的顺序(在单个线程内),还是可能重新排序某些内存访问?

2 个答案:

答案 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(但不是所有处理器!)保证订购。
我引用英特尔软件开发人员手册:

  

所有人都以相同的顺序观察单个处理器的写入   处理器。

多个处理器的写入情况并非如此 - 不同的处理器可能会对它们进行不同的排序。

但是,我强烈建议不要依赖它,而是使用正确的同步代替 同步原语使用原子操作和/或障碍实现,这样可以保证您的安全。