在C编程语言中,Pthreads作为线程库; 在线程之间共享的变量/结构是否需要声明为volatile?假设他们可能受到锁定或不受保护(可能是障碍).
pthread POSIX标准对此有任何发言权,是依赖于编译器还是不依赖于编译器?
编辑添加:感谢您的回答.但是,如果你不使用锁,那该怎么办?如果你使用障碍物怎么办?或者使用比较和交换等原语直接和原子地修改共享变量的代码......
只要您使用锁来控制对变量的访问,就不需要使用volatile.事实上,如果你在任何变量上放置volatile,你可能已经错了.
https://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/
答案是绝对的,毫不含糊的,不.除了正确的同步原语之外,您不需要使用'volatile'.需要完成的一切都是由这些原语完成的.
使用'volatile'既不必要也不充分.没有必要,因为适当的同步原语就足够了.这是不够的,因为它只会禁用一些优化,而不是所有可能会咬你的优化.例如,它不保证另一个CPU的原子性或可见性.
但除非你使用volatile,否则编译器可以自由地将共享数据缓存在寄存器中任何时间长度...如果你希望你的数据被写入可预测地写入实际内存而不是仅仅缓存在寄存器中编译器自行决定,您需要将其标记为volatile.或者,如果您在离开修改它的函数后才访问共享数据,那么您可能没问题.但我建议不要依赖盲目的运气来确保将值从寄存器写回到内存中.
是的,但即使您使用volatile,CPU也可以将共享数据缓存在写入发布缓冲区中任意长度.可以咬你的优化集与'volatile'禁用的优化集不完全相同.因此,如果你使用'volatile',你就是依靠盲目的运气.
另一方面,如果您使用具有已定义的多线程语义的sychronization原语,则可以保证事情能够正常工作.作为一个优点,你不会受到'volatile'的巨大打击.那么为什么不这样做呢?
我认为volatile的一个非常重要的属性是它在变量时将变量写入内存,并在每次访问时从内存重新读取.这里的其他答案混合了volatile和同步,从其他一些答案可以清楚地看出,volatile不是同步原语(信用到期的信用).
但除非你使用volatile,否则编译器可以自由地将共享数据缓存在寄存器中任何时间长度...如果你希望你的数据被写入可预测地写入实际内存而不是仅仅缓存在寄存器中编译器自行决定,您需要将其标记为volatile.或者,如果您在离开修改它的函数后才访问共享数据,那么您可能没问题.但我建议不要依赖盲目的运气来确保将值从寄存器写回到内存中.
特别是在富寄存器的机器上(即不是x86),变量可以在寄存器中存活很长时间,而良好的编译器甚至可以缓存寄存器中的部分结构或整个结构.所以你应该使用volatile,但是为了性能,还要将值复制到局部变量进行计算,然后进行显式回写.从本质上讲,有效地使用volatile意味着在C代码中进行一些加载存储思维.
在任何情况下,您都必须使用某种操作系统级别提供的同步机制来创建正确的程序.
有关volatile的弱点的一个例子,请参阅我在http://jakob.engbloms.se/archives/65上的 Decker算法示例,这证明了volatile不能同步.