假设线程Alpha
正在写锁定变量A
。第二个线程Beta
正在等待Alpha
终止,然后依次读取变量A
。如果第二个线程等待第一个线程的终止,是否需要内存屏障?
A
的内容有可能不新鲜吗?内存写入能否延迟超过线程生命周期?不会等待线程Alpha
终止的标准机制隐式地作为内存屏障吗?
UPDATE 1
是否存在不包括存储器屏障等待任何例子?
假设线程Alpha
正在写锁定变量A
。第二个线程Beta
正在等待Alpha
终止,然后依次读取变量A
。如果第二个线程等待第一个线程的终止,是否需要内存屏障?
A
的内容有可能不新鲜吗?内存写入能否延迟超过线程生命周期?不会等待线程Alpha
终止的标准机制隐式地作为内存屏障吗?
UPDATE 1
是否存在不包括存储器屏障等待任何例子?
几乎可以肯定(用于等待线程终止的API需要使用内存屏障来达到自己的目的),但是我认为对于明确的答案,您需要讨论所使用的特定线程API。
例如,POSIX使得对pthread_join()
这样的保证:https://stackoverflow.com/a/3208140/12711
和Win32文件,它是同步的API在对象上等待(例如,一个线程处理)处以记忆障碍:http://msdn.microsoft.com/en-us/library/ms686355.aspx
这取决于你的线程库提供了什么保证。特别是,pthread_join()是defined to be a memory barrier。在大多数情况下,线程加入将涉及内存障碍,但并非不可能总是如此。
(假设你指的是C#)。
如果你的意思Thread
从字面上看,那么你的答案取决于Thread.Join
是否隐含产生记忆障碍(其中,每已经给出答案,它可能不会) 。
但是,如果你的意思是Alpha
和Beta
是在后台线程(可能来自线程池)执行用户定义的任务,而“等待”是指两个任务,然后之间的用户级同步除非引入信令构造或显式障碍,否则数据更可能是而不是。
下面是一个简单的例子:
public class Program
{
static string A = "foo";
static volatile bool isAlphaReady = false;
static void Alpha()
{
A = "bar";
isAlphaReady = true;
}
static void Beta()
{
while (!isAlphaReady)
; // Wait by polling
Console.WriteLine(A);
}
static void Main(string[] args)
{
new Thread(Alpha).Start();
new Thread(Beta).Start();
Console.ReadKey();
}
}
虽然它出现(直觉地),该Beta
将始终输出"bar"
作为A
值,这不保证能够在弱同步行为的多处理器系统上(如Itanium),在这种情况下,可能会输出"foo"
。
我不认为这个例子适用于这种情况。我认为CLR确保写入后再写入从不交换。 – Imran 2013-07-05 09:11:52