【问题标题】:Two threads using a same variable两个线程使用同一个变量
【发布时间】:2012-03-06 14:03:58
【问题描述】:

我有两个线程:'main' 和 'worker',以及一个全局变量 bool isQuitRequestedmain 线程将使用它来通知 worker,何时该退出其 while 循环(类似于这个:while(isQuitRequested == false) { ... do some stuff ... })

现在,我有点担心... 考虑到只有一个线程 (main) 执行 isQuitRequested = true 操作,而另一个 (worker) 只执行检查而不执行其他操作,我是否需要对 isQuitRequested 使用某种互斥锁保护?

我已阅读What could happen if two threads access the same bool variable at the same time?。 我的情况类似,但情况不一样...

【问题讨论】:

    标签: c++ multithreading synchronization shared-state


    【解决方案1】:

    您尚未指定您使用的是哪种语言,并且从您发布的小代码 sn-p 中可以看出它可能是 C#、Java 或 C++。以下是针对每个“模式”的一些常见解决方案:

    C#:

    volatile bool isQuitRequested;
    

    Java:

    volatile boolean isQuitRequested;
    

    C++:C++ 中的volatile 几乎没有那么有用。一起去:

    std::atomic<bool> isQuitRequested;
    

    【讨论】:

    • 在像我这样的情况下,“volatile”还不够吗? (msdn.microsoft.com/en-us/library/12a04hfd(v=vs.80).aspx)关于“atomic”,我们在这里谈论的是“Boost.Atomic”吗? (chaoticmind.net/~hcb/projects/boost.atomic)
    • volatile is 在 C 中很有用。将其标记为 volatile 将强制编译器生成每次访问内存时从内存读取 isQuitRequested 的代码(不是缓存在寄存器中)。这不会导致内存栅栏等,但在所描述的场景中不需要这样做。
    • volatile 在 C++ 中只会阻止编译器优化(缓存),但不会阻止 CPU,它可能会执行自己的重新排序/缓存(尽管您是否真的需要它在 x86 上是有争议)。在 C#/Java 中,两者兼而有之。我提到的那个atomic实际上是std::atomic。我会编辑。
    【解决方案2】:

    使用volatile bool 应该是安全的,只要您没有在受生产者线程(将 bool 设置为 true)影响的消费者(检查 bool)线程中使用任何数据,并且在您消费者线程发现 bool 已设置为 true,它不会尝试重用/重置它作为与生产者线程通信的一种方式(如您链接的示例中所示)。

    这是因为这种情况使内存重新排序不再是问题。

    【讨论】:

    • 您的回答是最准确的恕我直言。在这里使用任何类型的同步对象(包括内存栅栏)都是过大的。唯一真正需要的是volatile关键字
    【解决方案3】:

    在 Java 中您只需将该变量标记为 volatile:

    volatile boolean isQuitRequested;
    

    或使用AtomicBoolean。否则,一个线程所做的更改可能不会被其他线程看到。

    但是,在您的情况下,有一个内置功能:只需在线程上调用 interrupt() 并处理它,请参阅:How to stop a thread that is running forever without any use

    另见:

    【讨论】:

      【解决方案4】:

      根据我在 Windows 上的经验,如果全局变量是 char、short、int、long 的基本类型之一,通常就足够了。 如果您想以“正确的方式”进行操作,@Tudor 的解决方案看起来不错。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-09
        • 1970-01-01
        • 2014-09-08
        • 1970-01-01
        • 1970-01-01
        • 2015-06-28
        • 1970-01-01
        • 2019-05-11
        相关资源
        最近更新 更多