首页 > 解决方案 > 如何防止另一个线程修改状态标志?

问题描述

我有一堂课

class Device
{
    enum State {eStopped, eRunning}
    State flag = eStopped;
public:
    void run(){
        if(flag==eRunning){return;}
        /*some codes to start this device*/
        flag = eRunning;
    }
    void stop(){
        if(flag==eStopped){return;}
        /*some codes to stop this device*/
        flag = eStopped;
    }
    void doMaintenance(){
        if(flag==eRunning){return;} // We can't do maintenance when the device is running
        /*Here, the flag may be modified to eRunning in other threads*/
    }
}

doMaintenance()函数中,检查flag后会被其他线程更改(flag==eRunning)。我如何优雅地防止这种情况发生?

标签: c++multithreadingc++11

解决方案


还有其他问题需要解决。例如,假设设备处于停止状态。然后,在两个线程中,您执行run(). 然后两个线程开始执行相同的启动顺序。我们也应该注意这一点。

因此,最简单的解决方案是不允许任何run(),stop()doMaintenance()同时运行。这可以通过互斥锁轻松解决:

class Device
{
    enum State {eStopped, eRunning}
    State flag = eStopped;
    std::mutex m_mutex;
public:
    void run(){
        std::scoped_lock lock(m_mutex);
        if(flag==eRunning){return;}
        /*some codes to start this device*/
        flag = eRunning;
    }
    void stop(){
        std::scoped_lock lock(m_mutex);
        if(flag==eStopped){return;}
        /*some codes to stop this device*/
        flag = eStopped;
    }
    void doMaintenance(){
        std::scoped_lock lock(m_mutex);
        if(flag==eRunning){return;} // We can't do maintenance when the device is running
        /*Here, the flag may be modified to eRunning in other threads*/
    }
}

推荐阅读