从多个线程访问此变量是否安全?

时间:2009-09-22 17:45:22

标签: c# thread-safety

我通常会编写这些代码:

public class MyClass
{
    static bool m_stop = false;

    public static void Main()
    {
        var th = new Thread(DoStuff);

        th.Start();

        Console.ReadLine();

        m_stop = true;

        th.Join();
    }

    private static void DoStuff()
    {
        while( !m_stop )
        {
            // do things here
        }
    }
}

...我总是同步访问变量m_stop,只是出于习惯。我想知道是否真的有必要这样做(假设在DoStuff()中运行一个或两个额外的循环不会伤害任何东西)。如果代码执行完全像这样可能会发生什么?我已经想到了为m_stop使用volatile关键字,但我不确定即使这是必要的。有人知道吗?

3 个答案:

答案 0 :(得分:4)

没有易失性且没有任何同步,您显示的代码不是线程安全的。一个线程可以更改变量的值,另一个线程可能从不看到它,永远循环。如果您使用公共锁同步对它的所有访问,则 是线程安全的。

现在波动性是一个棘手的话题 - 我认为直到最近才理解它,但它doesn't mean quite what I thought it did。但是,我很确定只要使变量volatile可以满足您的需要。

对于更复杂的事情,我通常会使用完全同步:每次访问共享数据时都要锁定。

答案 1 :(得分:1)

虽然这种方法没有技术上错误,但是当您的应用程序需要扩展时,您可能会遇到麻烦。如果您正在同步访问它,也不需要使m_stop易失。

答案 2 :(得分:0)

更新 m_stop 时必须放置内存屏障。因此,您必须将其标记为易失性(或自行放置内存屏障/易失性读写)