假设线程Alpha
正在写入变量A
而没有锁定。第二个帖子Beta
正在等待Alpha
终止,然后依次读取变量A
。
A
的内容是否有可能不新鲜?内存写入可以延迟超出线程生命周期吗?等待线程Alpha
终止的标准机制是否会隐含地作为内存屏障?
更新1
是否有任何不包含内存障碍的等待示例?
答案 0 :(得分:4)
几乎可以肯定(用于等待线程终止的API需要为自己的目的使用内存屏障),但我认为,要获得明确的答案,您需要讨论正在使用的特定线程API。
例如,posix为pthread_join()
:https://stackoverflow.com/a/3208140/12711
并且Win32记录了它在对象上等待的同步API(例如,线程句柄)强加了内存障碍:http://msdn.microsoft.com/en-us/library/ms686355.aspx
答案 1 :(得分:2)
这取决于您的线程库提供的保证。特别是,pthread_join()是defined to be a memory barrier。在大多数情况下,线程连接将涉及内存屏障,但是并非总是如此,这是不可想象的。
答案 2 :(得分:0)
(假设您指的是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"
。