How can I avoid the following race condition using condition variables? - c++

I have a recipe of several steps where each steps may or may not control a motor. For this, I created a thread that sends a command to the motor. I used to join that thread, as each steps needed to complete before going to the next one, but recently, I have a task of implementing a "Go to next step". The problem is that I cannot simply stop the motor upon clicking that button. The motor should only stop if the next step contains another movement. If that next step didn't move the motor, we wouldn't want to stop the motor.
For this, I created two variables, one that is set to true if the motor thread finished his movement, another that is set to true if a signal to go to the next step is received :
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::mutex m;
std::condition_variable cv;
bool signalReceived = false;
bool threadFinished = false;
void moveMotor() {
// If current step moves motor, stop any ongoing movement
// ...
// If current step moves motor, move the motor
// ...
// Set the threadFinished flag to true when the thread finishes
std::lock_guard<std::mutex> lock(m);
threadFinished = true;
signalReceived = false;
cv.notify_one();
}
void signalHandler() {
std::lock_guard<std::mutex> lock(m);
signalReceived = true;
cv.notify_one();
}
int main() {
while (true) {
std::thread motorThread(moveMotor);
motorThread.detach();
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [] { return threadFinished || signalReceived; });
if (threadFinished) {
std::cout << "The motor thread has finished." << std::endl;
}
if (signalReceived) {
std::cout << "A signal was received." << std::endl;
}
// Reset the flags for the next iteration
threadFinished = false;
signalReceived = false;
}
return 0;
}
I unfortunately have an issue with the above code. Let's have the following example :
In the first iteration (first step for example), a signal is emitted, and therefor, the main continues on to the second iteration .
In the second iteration , upon detaching the second thread, the first iteration thread finally finishes, setting the threadFinished variable to true. The second iteration will continue as if the second thread finished, which is not what I want.
How can I fix this?

Related

Best way to optimize timer queue with concurrent_priority_queue C++

I'm working on timer queue using concurrent_priority_queue right now..
I implemented basic logic of executing most urgent event in this queue.
Here's my code.
TimerEvent ev{};
while (timer.mLoop)
{
while (timer.mQueue.empty() == false)
{
if (timer.mQueue.try_pop(ev) == false)
continue;
if (ev.Type == EVENT_TYPE::PHYSICS) // Physics event is around 15 ~ 17ms
{
auto now = Clock::now();
std::this_thread::sleep_for(ev.StartTime - now);
timer.mGameServerPtr->PostPhysicsOperation(ev.WorldID);
}
else if (ev.Type == EVENT_TYPE::INVINCIBLE) // This event is 3sec long.
{
auto now = Clock::now();
std::this_thread::sleep_for(ev.StartTime - now); // This is wrong!!
timer.mGameServerPtr->ReleaseInvincibleMode(ev.WorldID);
}
}
std::this_thread::sleep_for(10ms);
}
The problem would be easily solved if there is like front/top method in concurrent_priority_queue.
But there is no such method in class because it isn't thread-safe.
So, I just popped event out of the queue and waited until start time of the event.
In this way, I shouldn't have to insert event into queue again.
But problem is that if I have another type of event like EVENT_TYPE::INVINCIBLE, then I shouldn't just use sleep_for because this event is almost 3 second long. While waiting for 3 second, the PHYSICS event will not executed in time.
I can use sleep_for method for PHYSIC event since it is most shortest one to wait.
But I have to re-insert INVINCIBLE event into queue.
How can I optimize this timer without re-insert event into queue again?
How can I optimize this timer without re-insert event into queue again?
By the looks of it, that'll be hard when using the implementation of concurrent_priority_queue you are currently using. It wouldn't be hard if you just used the standard std::priority_queue and added some locking where needed though.
Example:
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <queue>
using Clock = std::chrono::steady_clock;
using time_point = std::chrono::time_point<Clock>;
struct TimerEvent {
void operator()() { m_event(); }
bool operator<(const TimerEvent& rhs) const {
return rhs.StartTime < StartTime;
}
time_point StartTime;
std::function<void()> m_event; // what to execute when the timer is due
};
class TimerQueue {
public:
~TimerQueue() { shutdown(); }
void shutdown() {
m_shutdown = true;
m_cv.notify_all();
}
// add a new TimerEvent to the queue
template<class... Args>
void emplace(Args&&... args) {
std::scoped_lock lock(m_mutex);
m_queue.emplace(TimerEvent{std::forward<Args>(args)...});
m_cv.notify_all();
}
// Wait until it's time to fire the event that is first in the queue
// which may change while we are waiting, but that'll work too.
bool wait_pop(TimerEvent& ev) {
std::unique_lock lock(m_mutex);
while(!m_shutdown &&
(m_queue.empty() || Clock::now() < m_queue.top().StartTime))
{
if(m_queue.empty()) { // wait "forever"
m_cv.wait(lock);
} else { // wait until first StartTime
auto st = m_queue.top().StartTime;
m_cv.wait_until(lock, st);
}
}
if(m_shutdown) return false; // time to quit
ev = std::move(m_queue.top()); // extract event
m_queue.pop();
return true;
}
private:
std::priority_queue<TimerEvent> m_queue;
mutable std::mutex m_mutex;
std::condition_variable m_cv;
std::atomic<bool> m_shutdown{};
};
If an event that is due before the event we're currently waiting for in wait_pop comes in, the m_cv.wait/m_cv.wait_until will unblock (because of the m_cv.notify_all() in emplace()) and that new element will be the first in queue.
The event loop could simply be:
void event_loop(TimerQueue& tq) {
TimerEvent te;
while(tq.wait_pop(te)) {
te(); // execute event
}
// the queue was shutdown, exit thread
}
And you could put any kind of invocable with the time point when you'd like it to fire in that queue.
#include <thread>
int main() {
TimerQueue tq;
// create a thread to run the event loop
auto ev_th = std::thread(event_loop, std::ref(tq));
// wait a second
std::this_thread::sleep_for(std::chrono::seconds(1));
// add an event in 5 seconds
tq.emplace(Clock::now() + std::chrono::seconds(5), [] {
std::cout << "second\n";
});
// wait a second
std::this_thread::sleep_for(std::chrono::seconds(1));
// add an event in 2 seconds
tq.emplace(Clock::now() + std::chrono::seconds(2), [] {
std::cout << "first\n";
});
// sleep some time
std::this_thread::sleep_for(std::chrono::seconds(3));
// shutdown, only the event printing "first" will have fired
tq.shutdown();
ev_th.join();
}
Demo with logging

C++ Lock a mutex as if from another thread?

I'm writing an Audio class that holds an std::thread for refilling some buffers asynchronously. Say we call the main thread A and the background (class member) thread B. I'm using an std::mutex to block thread B whenever the sound is not playing, that way it doesn't run in the background when unnecessary and doesn't use excess CPU power. The mutex locked by thread A by default, so thread B is blocked, then when it's time to play the sound thread A unlocks the mutex and thread B runs (by locking then immediately unlocking it) in a loop.
The issue comes up when thread B sees that it's reached the end of the file. It can stop playback and clean up buffers and such, but it can't stop its own loop because thread B can't lock the mutex from thread A.
Here's the relevant code outline:
class Audio {
private:
// ...
std::thread Thread;
std::mutex PauseMutex; // mutex that blocks Thread, locked in constructor
void ThreadFunc(); // assigned to Thread in constructor
public:
// ...
void Play();
void Stop();
}
_
void Audio::ThreadFunc() {
// ... (include initial check of mutex here)
while (!this->EndThread) { // Thread-safe flag, only set when Audio is destructed
// ... Check and refill buffers as necessary, etc ...
if (EOF)
Stop();
// Attempt a lock, blocks thread if sound/music is not playing
this->PauseMutex.lock();
this->PauseMutex.unlock();
}
}
void Audio::Play() {
// ...
PauseMutex.unlock(); // unlock mutex so loop in ThreadFunc can start
}
void Audio::Stop() {
// ...
PauseMutex.lock(); // locks mutex to stop loop in ThreadFunc
// ^^ This is the issue here
}
In the above setup, when the background thread sees that it's reached EOF, it would call the class's Stop() function, which supposedly locks the mutex to stop the background thread. This doesn't work because the mutex would have to be locked by the main thread, not the background thread (in this example, it crashes in ThreadFunc because the background thread attempts a lock in its main loop after already locking in Stop()).
At this point the only thing I could think of would be to somehow have the background thread lock the mutex as if it was the main thread, giving the main thread ownership of the mutex... if that's even possible? Is there a way for a thread to transfer ownership of a mutex to another thread? Or is this a design flaw in the setup I've created? (If the latter, are there any rational workarounds?) Everything else in the class so far works just as designed.
I'm not going to even pretend to understand how your code is trying to do what it is doing. There is one thing, however, that is evident. You're trying to use a mutex for conveying some predicate state change, which is the wrong vehicle to drive on that freeway.
Predicate state change is handled by coupling three things:
Some predicate datum
A mutex to protect the predicate
A condition variable to convey possible change in predicate state.
The Goal
The goal in the below example is to demonstrate how a mutex, a condition variable, and predicate data are used in concert when controlling program flow across multiple threads. It shows examples of using both wait and wait_for condition variable functionality, as well as one way to run a member function as a thread proc.
Following is a simple Player class toggles between four possible states:
Stopped : The player is not playing, nor paused, nor quitting.
Playing : The player is playing
Paused : The player is paused, and will continue from whence it left off once it resumes Playing.
Quit : The player should stop what it is doing and terminate.
The predicate data is fairly obvious. the state member. It must be protected, which means it cannot be changed nor checked unless under the protection of the mutex. I've added to this a counter that simply increments during the course of maintaining the Playing state for some period of time. more specifically:
While Playing, each 200ms the counter increments, then dumps some data to the console.
While Paused, counter is not changed, but retains its last value while Playing. This means when resumed it will continue from where it left off.
When Stopped, the counter is reset to zero and a newline is injected into the console output. This means switching back to Playing will start the counter sequence all over again.
Setting the Quit state has no effect on counter, it will be going away along with everything else.
The Code
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <unistd.h>
using namespace std::chrono_literals;
struct Player
{
private:
std::mutex mtx;
std::condition_variable cv;
std::thread thr;
enum State
{
Stopped,
Paused,
Playing,
Quit
};
State state;
int counter;
void signal_state(State st)
{
std::unique_lock<std::mutex> lock(mtx);
if (st != state)
{
state = st;
cv.notify_one();
}
}
// main player monitor
void monitor()
{
std::unique_lock<std::mutex> lock(mtx);
bool bQuit = false;
while (!bQuit)
{
switch (state)
{
case Playing:
std::cout << ++counter << '.';
cv.wait_for(lock, 200ms, [this](){ return state != Playing; });
break;
case Stopped:
cv.wait(lock, [this]() { return state != Stopped; });
std::cout << '\n';
counter = 0;
break;
case Paused:
cv.wait(lock, [this]() { return state != Paused; });
break;
case Quit:
bQuit = true;
break;
}
}
}
public:
Player()
: state(Stopped)
, counter(0)
{
thr = std::thread(std::bind(&Player::monitor, this));
}
~Player()
{
quit();
thr.join();
}
void stop() { signal_state(Stopped); }
void play() { signal_state(Playing); }
void pause() { signal_state(Paused); }
void quit() { signal_state(Quit); }
};
int main()
{
Player player;
player.play();
sleep(3);
player.pause();
sleep(3);
player.play();
sleep(3);
player.stop();
sleep(3);
player.play();
sleep(3);
}
Output
I can't really demonstrate this. You'll have to run it and see how it works, and I invite you to toy with the states in main() as I have above. Do note, however, that once quit is invoked none of the other stated will be monitored. Setting the Quit state will shut down the monitor thread. For what its worth, a run of the above should look something like this:
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.
with the first set of numbers dumped in two groups (1..15, then 16..30), as a result of playing, then pausing, then playing again. Then a stop is issued, followed by another play for a period of ~3 seconds. After that, the object self-destructs, and in doing so, sets the Quit state, and waits for the monitor to terminate.
Summary
Hopefully you get something out of this. If you find yourself trying to manage predicate state by manually latching and releasing mutexes, changes are you need a condition-variable design patter to facilitate detecting those changes.
Hope you get something out of it.
class CtLockCS
{
public:
//--------------------------------------------------------------------------
CtLockCS() { ::InitializeCriticalSection(&m_cs); }
//--------------------------------------------------------------------------
~CtLockCS() { ::DeleteCriticalSection(&m_cs); }
//--------------------------------------------------------------------------
bool TryLock() { return ::TryEnterCriticalSection(&m_cs) == TRUE; }
//--------------------------------------------------------------------------
void Lock() { ::EnterCriticalSection(&m_cs); }
//--------------------------------------------------------------------------
void Unlock() { ::LeaveCriticalSection(&m_cs); }
//--------------------------------------------------------------------------
protected:
CRITICAL_SECTION m_cs;
};
///////////////////////////////////////////////////////////////////////////////
// class CtLockMX - using mutex
class CtLockMX
{
public:
//--------------------------------------------------------------------------
CtLockMX(const TCHAR* nameMutex = 0)
{ m_mx = ::CreateMutex(0, FALSE, nameMutex); }
//--------------------------------------------------------------------------
~CtLockMX()
{ if (m_mx) { ::CloseHandle(m_mx); m_mx = NULL; } }
//--------------------------------------------------------------------------
bool TryLock()
{ return m_mx ? (::WaitForSingleObject(m_mx, 0) == WAIT_OBJECT_0) : false; }
//--------------------------------------------------------------------------
void Lock()
{ if (m_mx) { ::WaitForSingleObject(m_mx, INFINITE); } }
//--------------------------------------------------------------------------
void Unlock()
{ if (m_mx) { ::ReleaseMutex(m_mx); } }
//--------------------------------------------------------------------------
protected:
HANDLE m_mx;
};
///////////////////////////////////////////////////////////////////////////////
// class CtLockSM - using semaphore
class CtLockSM
{
public:
//--------------------------------------------------------------------------
CtLockSM(int maxcnt) { m_sm = ::CreateSemaphore(0, maxcnt, maxcnt, 0); }
//--------------------------------------------------------------------------
~CtLockSM() { ::CloseHandle(m_sm); }
//--------------------------------------------------------------------------
bool TryLock() { return m_sm ? (::WaitForSingleObject(m_sm, 0) == WAIT_OBJECT_0) : false; }
//--------------------------------------------------------------------------
void Lock() { if (m_sm) { ::WaitForSingleObject(m_sm, INFINITE); } }
//--------------------------------------------------------------------------
void Unlock()
{
if (m_sm){
LONG prevcnt = 0;
::ReleaseSemaphore(m_sm, 1, &prevcnt);
}
}
//--------------------------------------------------------------------------
protected:
HANDLE m_sm;
};

C++ Wait for bool to change in another class

I have a Program class and a Browser class.
Inside my Program::Run(), I launch the Browser to start in a separate thread.
However, before I continue with my Run() method, I want to wait for a certain part of the Browser to initialize, thus I need to check if a variable has been set in the browser object.
Used as the thread for the browser
int Program::_Thread_UI_Run() {
...
return Browser->Run();
}
I am using async to run the browser thread and retrieve its return value when it is finished.
int Program::Start() {
std::unique_lock<std::mutex> lck(mtx);
auto t1 = std::async(&Program::_Thread_Browser_Run, this);
cv.wait(lck);
... when wait is released, do stuff
// Thread finishes and returns an exit code for the program
auto res1 = f1.get();
// return res1 as exit code.
}
Browser.cpp class
int Browser::Run()
{
// Initialize many things
...
m_Running = true;
cv.notify_all(); // Notify the waiter back in Program
// This will run for as long as the program is running
while (m_Running)
{
... browser window message loop
}
return exit_code;
}
I have problems setting this up. The program is crashing :/
Do I pass the mutex variable to everything using it? Or just recreate it in every function body?
What about the conditional_variable?
With the current setup the program crashes:
The exception Breakpoint
A breakpoint has been reached.
(0x80000003) occured in the application at location 0x107d07d6.
Hints and help is appreciated
Edit: Updated code to match new suggestions
In browser's .h file: std::atomic_bool m_Running;
int Browser::Run(std::condition_variable& cv)
{
int exit_code = 0;
// Set up, and attain the desired state:
...
m_Running = true;
cv.notify_all();
while (m_Running)
{
// Process things etc
}
return exit_code;
}
int Program::Start()
{
std::mutex m;
std::condition_variable cv;
auto t1 = std::async(&Program::_Thread_UI_Run, this, std::ref(cv));
std::unique_lock<std::mutex> lock(m);
cv.wait(lock);
.... stuff
return t1.get();
}
I have a logger that helps me keep track of how the program is running.
By placing logger calls in crucial places in the code I was able to confirm that the program waits appropiately before continuing. However I still get prompted with
The exception Breakpoint A breakpoint has been reached. (0x80000003)
occured in the application at location 0x107d07d6.
By commenting out //cv.wait(lock); the program resumes to work.. :/
Why would waiting making it crash like that?
You definitely want to use std::condition_variable. It allows you to signal other threads once an operation has complete, so in your case, once the bool has been set:
Browser::Run()
{
// Set some things up, make sure everything is okay:
...
m_Running = true; // Now the thread is, by our standards, running*
// Let other threads know:
cv.notify_all();
// Continue to process thread:
while (m_Running)
{
}
}
And then in your main / other thread:
auto t1 = std::async(&Program::_Thread_Browser_Run, this);
// Wait until we know the thread is actually running. This will pause this thread indefinitely until the condition_variable signals.
cv.wait();
You should pass the std::condition_variable into any function using it, so your code would look more like:
int Browser::Run(std::condition_variable& cv)
{
int exit_code = 0;
// Set up, and attain the desired state:
...
m_Running = true;
cv.notify_all();
while (m_Running)
{
// Process things etc
}
return exit_code;
}
int Program::Start()
{
std::mutex m;
std::condition_variable cv;
auto t1 = std::async(&Program::_Thread_UI_Run, this, std::ref(cv));
std::unique_lock<std::mutex> lock(m);
// Wait until the browser is in the desired state
cv.wait(lock);
// The thread has signalled. At this point, Browser::m_Running = true
// Wait for the browser to exit, and then propagate its exit code
return t1.get();
}
#Richard Hodges raises an excellent point in the comments, which I overlooked: m_Running needs to be std::atomic (or have locking around its use) otherwise both threads may try to use it once. std::condition_variable is thread-safe and doesn't require locking around it.
*Of course the thread is running at that point, I just mean it's in the state you desire

Basic timer with std::thread and std::chrono

I'm trying to implement a basic timer with the classic methods: start() and stop(). I'm using c++11 with std::thread and std::chrono.
Start method. Creates a new thread that is asleep for a given interval time, then execute a given std::function. This process is repeated while a 'running' flag is true.
Stop method. Just sets the 'running' flag to false.
I created and started a Timer object that show "Hello!" every second, then with other thread I try to stop the timer but I can't. The Timer never stops.
I think the problem is with th.join()[*] that stops execution until the thread has finished, but when I remove th.join() line obviously the program finishes before the timer start to count.
So, my question is how to run a thread without stop other threads?
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
class Timer
{
thread th;
bool running = false;
public:
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
void start(const Interval &interval,
const Timeout &timeout)
{
running = true;
th = thread([=]()
{
while (running == true) {
this_thread::sleep_for(interval);
timeout();
}
});
// [*]
th.join();
}
void stop()
{
running = false;
}
};
int main(void)
{
Timer tHello;
tHello.start(chrono::milliseconds(1000),
[]()
{
cout << "Hello!" << endl;
});
thread th([&]()
{
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
});
th.join();
return 0;
}
Output:
Hello!
Hello!
...
...
...
Hello!
In Timer::start, you create a new thread in th and then immediately join it with th.join(). Effectively, start won't return until that spawned thread exits. Of course, it won't ever exit because nothing will set running to false until after start returns...
Don't join a thread until you intend to wait for it to finish. In this case, in stop after setting running = false is probably the correct place.
Also - although it's not incorrect - there's no need to make another thread in main to call this_thread::sleep_for. You can simply do so with the main thread:
int main()
{
Timer tHello;
tHello.start(chrono::milliseconds(1000), []{
cout << "Hello!" << endl;
});
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
}
Instead of placing the join in start place it after running = false in stop. Then the stop method will effectively wait until the thread is completed before returning.

How to use a thread to break a loop in main c++

I am using the following thread in c++ to check if a certain condition is met and if so then it should break the loop. I call the thread in a while loop so I need that to break.
The refresh token is updated by another thread.
void ThreadCheck( void* pParams )
{
if(refresh)
{
continue;
}
}
My while loop:-
while(crun)
{
refresh = false;
_beginthread( ThreadCheck, 0, NULL );
rlutil::setColor(8);
cout<<"Send>> ";
getline(cin, msg); //Make a custom function of this.
if(stricmp(msg.c_str(), "exit")==0)
{
crun = false;
}
else if(msg.empty() || stricmp(msg.c_str()," ")==0)
{
rlutil::setColor(4);
cout<<"Plz enter a valid message!\n";
continue;
} else {
manager('c', msg);
// msg.append("\n");
// chat_out<<msg;
// chat_out.close();
}
cout<<"\n";
}
You cannot modify a value in one thread while another thread is, or might be, accessing it. You need to use some form of synchronization, such as a lock.
You have 2 threads : 1) main, 2) ThreadCheck. Add a mutex so as not to update the 'crun' at the same time and inside the thread update the value to false. That's it
#include <iostream>
#include "/tbb/mutex.h"
#include "/tbb/tbb_thread.h"
using namespace tbb;
typedef mutex myMutex;
static myMutex sm;
int i = 0;
void ThreadCheck( )
{
myMutex::scoped_lock lock;//create a lock
lock.acquire(sm);//Method acquire waits until it can acquire a lock on the mutex
//***only one thread can access the lines from here...***
crun = false;;//update is safe (only one thread can execute the code in this scope) because the mutex locked above protects all lines of code until the lock release.
sleep(1);//simply creating a delay to show that no other thread can update
std::cout<<"ThreadCheck "<<"\n";
//***...to here***
lock.release();//releases the lock (duh!)
}
int main()
{
tbb_thread my_thread(ThreadCheck);//create a thread which executes 'someFunction'
// ... your code
my_thread.join();//This command causes the main thread (which is the 'calling-thread' in this case) to wait until thread1 completes its task.
}