如何防止另一个线程修改状态标志?

时间:2019-09-18 07:40:17

标签: c++ multithreading c++11

我上课

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)。我如何优雅地防止这种情况发生?

1 个答案:

答案 0 :(得分:3)

还有其他问题需要解决。例如,假设设备处于停止状态。然后,在两个线程中,执行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*/
    }
}