如果第二个线程等待第一个线程终止,是否需要内存屏障?

时间:2012-02-10 08:02:21

标签: multithreading synchronization multiprocessing memory-barriers

假设线程Alpha正在写入变量A而没有锁定。第二个帖子Beta正在等待Alpha终止,然后依次读取变量A

A的内容是否有可能不新鲜?内存写入可以延迟超出线程生命周期吗?等待线程Alpha终止的标准机制是否会隐含地作为内存屏障?

更新1

是否有任何不包含内存障碍的等待示例?

3 个答案:

答案 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是否隐含地产生了记忆障碍(根据已经给出的答案,它可能确实存在)。

但是,如果您的意思是AlphaBeta是在后台线程(可能来自线程池)上执行的用户定义任务,并且“等待”是指用户级之间的同步两个任务,那么除非引入信号构造或明确的障碍,否则数据的可能性更大。

这是一个简单的例子:

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"