如果第二个线程等待第一个线程的终止,是否需要内存屏障?
假设线程 Alpha
正在写入变量 A
而没有锁定。第二个线程 Beta
正在等待 Alpha
终止,然后依次读取变量 A
。
难道A
的内容就不会新鲜了?内存写入是否可以延迟到线程生命周期之外?等待线程 Alpha 终止的标准机制不会隐式地充当内存屏障吗?
更新1
是否有任何不包括内存屏障的等待示例?
Suppose that thread Alpha
is writing to variable A
without locking. A second thread Beta
is waiting for Alpha
to terminate, then reads the variable A
in turn.
Is it possible that the contents of A
will not be fresh? Can memory writes be delayed beyond the thread lifetime? Won't the standard mechanism of waiting for thread Alpha
termination implicitly work as a memory barrier?
UPDATE 1
Are there any examples of waiting which does not include a memory barrier?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
几乎可以肯定(用于等待线程终止的 API 需要使用内存屏障来实现其自身目的),但我认为要获得明确的答案,您需要讨论正在使用的特定线程 API。
例如,posix 对 pthread_join() 做出这样的保证:https://stackoverflow.com/a/ 3208140/12711
并且 Win32 文档表明等待对象(例如线程句柄)的同步 API 会施加内存屏障:http://msdn.microsoft.com/en-us/library/ms686355.aspx< /a>
Almost certainly (the API used to wait for thread termination would need to use memory barriers for its own purposes), but I think for a definitive answer you'll need to talk about the specific threading API being used.
For example, posix makes such a guarantee for
pthread_join()
: https://stackoverflow.com/a/3208140/12711And Win32 documents that it's synchronization APIs to wait on an object (for example, a thread handle) impose memory barriers: http://msdn.microsoft.com/en-us/library/ms686355.aspx
这取决于您的线程库提供的保证。特别是,pthread_join()定义为内存屏障 。在大多数情况下,线程连接会涉及内存屏障,但情况并非总是如此,这并非不可想象。
This depends on what guarantees your threading library provides. In particular, pthread_join() is defined to be a memory barrier. In most cases thread joining will involve a memory barrier, but it is not inconceivable that this may not always be the case.
(假设您指的是 C#。)
如果您的意思是字面上的
Thread
,那么您的答案取决于Thread.Join
是否隐式生成内存屏障(根据已经给出的答案,可能是这样)。但是,如果您的意思是
Alpha
和Beta
是在后台线程(可能来自线程池)上执行的用户定义任务,并且“等待”指的是用户-如果两个任务之间的级别同步,那么数据很可能不是新鲜的,除非引入信令构造或显式屏障。这是一个简单的例子:
虽然(直观上)
Beta
总是输出"bar"
作为A
的值,但这不是在具有弱同步行为的多处理器系统(例如 Itanium)上得到保证,在这种情况下,可能会输出"foo"
。(Assuming you’re referring to C#.)
If you mean
Thread
literally, then your answer depends on whetherThread.Join
implicitly generates memory barriers (which, per the answers already given, it probably does).However, if you mean that
Alpha
andBeta
are user-defined tasks executed on a background thread (possibly from the thread pool), and that “waiting” refers to user-level synchronization between the two tasks, then it’s more likely that the data will not be fresh, unless a signaling construct or an explicit barrier is introduced.Here is a trivial example:
Although it appears (intuitively) that
Beta
will always output"bar"
as the value ofA
, this is not guaranteed on a multiprocessor system with weak synchronization behaviour (such as Itanium), in which case,"foo"
may be output instead.