0

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

A会不会内容不新鲜?内存写入可以延迟到线程生命周期之外吗?等待线程终止的标准机制不会Alpha隐含地充当内存屏障吗?

更新 1

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

4

3 回答 3

4

几乎可以肯定(用于等待线程终止的 API 需要为自己的目的使用内存屏障),但我认为要获得明确的答案,您需要讨论正在使用的特定线程 API。

例如,posix 为pthread_join()https ://stackoverflow.com/a/3208140/12711 做出这样的保证

并且 Win32 文件表明它的同步 API 等待对象(例如,线程句柄)施加内存障碍:http: //msdn.microsoft.com/en-us/library/ms686355.aspx

于 2012-02-10T08:08:33.327 回答
3

这取决于您的线程库提供的保证。特别是, pthread_join() 被定义为内存屏障。在大多数情况下,线程连接会涉及内存屏障,但并非总是如此,这并非不可想象。

于 2012-02-10T08:09:44.457 回答
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"可能会改为输出。

于 2012-02-10T19:45:46.463 回答