假设线程Alpha
正在写入变量A
而没有锁定。第二个线程Beta
正在等待Alpha
终止,然后依次读取变量A
。
A
会不会内容不新鲜?内存写入可以延迟到线程生命周期之外吗?等待线程终止的标准机制不会Alpha
隐含地充当内存屏障吗?
更新 1
是否有任何不包括内存屏障的等待示例?
假设线程Alpha
正在写入变量A
而没有锁定。第二个线程Beta
正在等待Alpha
终止,然后依次读取变量A
。
A
会不会内容不新鲜?内存写入可以延迟到线程生命周期之外吗?等待线程终止的标准机制不会Alpha
隐含地充当内存屏障吗?
更新 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() 被定义为内存屏障。在大多数情况下,线程连接会涉及内存屏障,但并非总是如此,这并非不可想象。
(假设您指的是 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"
可能会改为输出。