一位读者 一位作家.关于互斥体和原子内置函数的一些常见问题

Kos*_*lma 7 c++ multithreading mutex

我有一个父级和一个工作线程共享一个bool标志和一个std :: vector.父只读取(即读取bool或调用my_vector.empty()); 工人只写.

我的问题:

  • 我需要互斥保护bool旗吗?

  • 我可以说所有bool读/写都是固有的原子操作吗?如果您说"是"或"否",您从哪里获取信息?

  • 我最近听说过GCC Atomic-builtin.我可以使用这些来使我的标志读/写原子而不必使用互斥锁吗?有什么不同?我理解Atomic builtins归结为机器代码,但即使是互斥体也归结为CPU的内存屏障指令吧?为什么人们将互斥锁称为"操作系统级别"构造?

  • 我需要互斥保护我的std :: vector吗?回想一下,工作线程填充这个向量,而父对象只调用它上面的empty()(即只读取它)

  • 我不相信bool或vector都需要互斥保护.我合理化如下,"好吧,如果我在更新之前读取共享内存...那仍然没问题,我将在下一次获得更新的值.更重要的是,我不明白为什么写入者应该被阻止阅读正在阅读,因为毕竟,读者只是在阅读!"

如果有人可以指出我正确的方向,那将是非常好的.我在GCC 4.3上,而Intel x86是32位.非常感谢!

Max*_*kin 13

我需要互斥保护bool旗吗?

不一定,原子指令会这样做.通过atomic instruction我的意思是一个编译器本征函数是:a)防止编译器重新排序/优化和b)导致原子的读/写和c)就发出一个适当的存储栅栏,以确保CPU之间的可见性(不需要其采用电流x86 CPU的MESI高速缓存一致性协议).与gcc atomic builtins类似.

我可以说所有bool读/写都是固有的原子操作吗?如果您说"是"或"否",您从哪里获取信息?

取决于CPU.对于英特尔CPU - 是的.请参阅英特尔®64和IA-32架构软件开发人员手册.

我最近听说过GCC Atomic-builtin.我可以使用这些来使我的标志读/写原子而不必使用互斥锁吗?有什么不同?我理解Atomic builtins归结为机器代码,但即使是互斥体也归结为CPU的内存屏障指令吧?为什么人们将互斥锁称为"操作系统级别"构造?

原子和互斥体之间的区别在于后者可以让等待线程进入睡眠状态,直到释放互斥锁.使用原子,你只能忙着旋转.

我需要互斥保护我的std :: vector吗?回想一下,工作线程填充这个向量,而父对象只调用它上面的empty()(即只读取它)

你做.

我不相信bool或vector都需要互斥保护.我合理化如下,"好吧,如果我在更新之前读取共享内存...那仍然没问题,我将在下一次获得更新的值.更重要的是,我不明白为什么写入者应该被阻止阅读正在阅读,因为毕竟,读者只是在阅读!"

根据实现,vector.empty()可能涉及读取两个缓冲区开始/结束指针并减去或比较它们,因此您有可能在没有互斥锁的情况下读取一个指针的新版本和另一个指针的旧版本.可能会出现令人惊讶的行为.