我上课
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)
。我如何优雅地防止这种情况发生?
答案 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*/
}
}