Reputation: 3356
I have a class
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*/
}
}
In the doMaintenance()
function, flag
would be changed by other threads after the (flag==eRunning)
check. How do I gracefully prevent this happening?
Upvotes: 0
Views: 98
Reputation: 29970
There are other problems to solve as well. For example, suppose that the device is in a stopped state. Then, in two threads, you execute run()
. Then two threads start to execute the same starting sequence. We should take care of this as well.
So, the simplest solution is to not allow any of the run()
, stop()
and doMaintenance()
to run concurrently. This can be easily solved by a mutex:
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*/
}
}
Upvotes: 3