当另一个线程可能设置它(最多一次)时,可以读取共享布尔标志而不锁定它吗?

我希望我的线程更优雅地关闭,所以我尝试实现一个简单的信号机制.我不认为我想要一个完全事件驱动的线程,所以我有一个工作人员可以使用关键部分 Monitor 优雅地停止它(相当于 C# lock我相信):

绘图线程.h

class DrawingThread {
    bool stopRequested;
    Runtime::Monitor CSMonitor;
    CPInfo *pPInfo;
    //More..
}

绘图线程.cpp

void DrawingThread::Run() {
    if (!stopRequested)
        //Time consuming call#1
    if (!stopRequested) {
        CSMonitor.Enter();
        pPInfo = new CPInfo(/**/);
        //Not time consuming but pPInfo must either be null or constructed. 
        CSMonitor.Exit();
    }
    if (!stopRequested) {
        pPInfo->foobar(/**/);//Time consuming and can be signalled
    }
    if (!stopRequested) {
        //One more optional but time consuming call.
    }
}


void DrawingThread::RequestStop() {
    CSMonitor.Enter();
    stopRequested = true;
    if (pPInfo) pPInfo->RequestStop();
    CSMonitor.Exit();
}

我了解(至少在 Windows 中)Monitor/lock 是最便宜的线程同步原语,但我希望避免过度使用.我应该包装这个布尔标志的每次读取吗?它被初始化为 false,并且仅在请求停止时设置一次为 true(如果在任务完成之前请求它).

我的导师建议保护甚至 bool 的,因为读/写可能不是原子的.我觉得这个一击旗是证明规则的例外?

liweisb 回答:当另一个线程可能设置它(最多一次)时,可以读取共享布尔标志而不锁定它吗?

在没有同步的情况下读取可能在不同线程中修改的内容是永远不会好的.需要什么级别的同步取决于您实际阅读的内容.对于原始类型,您应该查看原子读取,例如std::atomic<bool>.

始终需要同步的原因是处理器将可能在高速缓存行中共享数据.如果没有同步,则没有理由将此值更新为可能在不同线程中更改的值.更糟糕的是,如果没有同步,如果存储在该值附近的内容被更改和同步,它可能会写入错误的值.

这篇关于当另一个线程可能设置它(最多一次)时,可以读取共享布尔标志而不锁定它吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持前端之家!

本文链接:https://www.f2er.com/3181266.html

大家都在问