How to wake an std::thread while it is sleeping

Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.
// MyClass.hpp
MyClass
~MyClass();
RunMyThread();
private:
std::thread my_thread;
std::atomic<bool> m_running;
MyClass::RunMyThread()
my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);
;
// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?
Issue:
The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.
Question:
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
c++ c++11 mutex condition-variable stdthread
add a comment |Â
up vote
6
down vote
favorite
I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.
// MyClass.hpp
MyClass
~MyClass();
RunMyThread();
private:
std::thread my_thread;
std::atomic<bool> m_running;
MyClass::RunMyThread()
my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);
;
// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?
Issue:
The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.
Question:
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
c++ c++11 mutex condition-variable stdthread
Note that the code you've shown is full of syntax errors.
â François Andrieux
1 hour ago
Remember tojointhestd::threadin the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
â François Andrieux
1 hour ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
1 hour ago
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.
// MyClass.hpp
MyClass
~MyClass();
RunMyThread();
private:
std::thread my_thread;
std::atomic<bool> m_running;
MyClass::RunMyThread()
my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);
;
// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?
Issue:
The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.
Question:
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
c++ c++11 mutex condition-variable stdthread
I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.
// MyClass.hpp
MyClass
~MyClass();
RunMyThread();
private:
std::thread my_thread;
std::atomic<bool> m_running;
MyClass::RunMyThread()
my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);
;
// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?
Issue:
The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.
Question:
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
c++ c++11 mutex condition-variable stdthread
c++ c++11 mutex condition-variable stdthread
edited 1 hour ago
asked 1 hour ago
Game_Of_Threads
1,36511138
1,36511138
Note that the code you've shown is full of syntax errors.
â François Andrieux
1 hour ago
Remember tojointhestd::threadin the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
â François Andrieux
1 hour ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
1 hour ago
add a comment |Â
Note that the code you've shown is full of syntax errors.
â François Andrieux
1 hour ago
Remember tojointhestd::threadin the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
â François Andrieux
1 hour ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
1 hour ago
Note that the code you've shown is full of syntax errors.
â François Andrieux
1 hour ago
Note that the code you've shown is full of syntax errors.
â François Andrieux
1 hour ago
Remember to
join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.â François Andrieux
1 hour ago
Remember to
join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.â François Andrieux
1 hour ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
1 hour ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
1 hour ago
add a comment |Â
6 Answers
6
active
oldest
votes
up vote
4
down vote
How can I use an
std::condition_variableto wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same withoutcondition_variabletechnique?
No, not in standard C++ as of C++17 (there are of course non-standard, platform-specific ways to do it, and it's likely some kind of semaphore will be added to C++2a).
Additionally, I see that I need to use a
std::mutexin conjunction withstd::condition_variable? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variablelogic only to required places in the code piece here?
No. For a start, you can't wait on a condition_variable without locking a mutex (and passing the lock object to the wait function) so you need to have a mutex present anyway. Since you have to have a mutex anyway, requiring both the waiter and the notifier to use that mutex isn't such a big deal.
Condition variables are subject to "spurious wake ups" which means they can stop waiting for no reason. In order to tell if it woke because it was notified, or woke spuriously, you need some state variable that is set by the notifying thread and read by the waiting thread. Because that variable is shared by multiple threads it needs to be accessed safely, which the mutex ensures.
Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications.
This is all explained in more detail in
https://github.com/isocpp/CppCoreGuidelines/issues/554
1
"Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
â François Andrieux
1 hour ago
add a comment |Â
up vote
2
down vote
There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.
Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.
Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.
Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.
add a comment |Â
up vote
2
down vote
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?
You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.
add a comment |Â
up vote
1
down vote
A working example for you using std::condition_variable:
struct MyClass
MyClass()
: my_thread([this]() this->thread(); )
~MyClass()
std::lock_guard<std::mutex> l(m_);
stop_ = true;
c_.notify_one();
my_thread.join();
void thread()
for(;;)
std::unique_lock<std::mutex> l(m_);
if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
return; // stop_ == true.
SendStatusInfo(some_info);
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
add a comment |Â
up vote
0
down vote
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.
struct timed_waiter
void interrupt()
auto l = lock();
interrupted = true;
cv.notify_all();
// returns false if interrupted
template<class Rep, class Period>
bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
auto l = lock();
return !cv.wait_until( l,
std::chrono::steady_clock::now() + how_long,
[&]
return !interrupted;
);
private:
std::unique_lock<std::mutex> lock() const
return std::unique_lock<std::mutex>(m);
mutable std::mutex m;
mutable std::condition_variable cv;
bool interrupted = false;
;
simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.
The waiting threads do
while(m_timer.wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.
Live example:
struct MyClass
~MyClass();
void RunMyThread();
private:
std::thread my_thread;
timed_waiter m_timer;
;
void MyClass::RunMyThread()
my_thread = std::thread
[this]
while(m_timer.wait_for(std::chrono::seconds(2)))
std::cout << "SendStatusInfo(some_info)n";
;
// Destructor
MyClass::~MyClass()
std::cout << "~MyClass::MyClassn";
m_timer.interrupt();
my_thread.join();
std::cout << "~MyClass::MyClass donen";
int main()
std::cout << "start of mainn";
MyClass x;
x.RunMyThread();
using namespace std::literals;
std::this_thread::sleep_for(11s);
std::cout << "end of mainn";
add a comment |Â
up vote
0
down vote
Or are there any other ways of achieving the same without condition_variable technique?
One alternative to a condition variable is you can wake your thread up at much more regular intervals to check the "running" flag and go back to sleep if it is not set and the allotted time has not yet expired:
void periodically_call(std::atomic_bool& running, std::chrono::milliseconds wait_time)
auto wake_up = std::chrono::steady_clock::now();
while(running)
wake_up += wait_time; // next signal send time
while(std::chrono::steady_clock::now() < wake_up)
if(!running)
break;
// sleep for just 1/10 sec (maximum)
auto pre_wake_up = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
pre_wake_up = std::min(wake_up, pre_wake_up); // don't overshoot
// keep going to sleep here until full time
// has expired
std::this_thread::sleep_until(pre_wake_up);
SendStatusInfo(some_info); // do the regular call
Note: You can make the actual wait time anything you want. In this example I made it 100ms std::chrono::milliseconds(100). It depends how responsive you want your thread to be to a signal to stop.
For example in one application I made that one whole second because I was happy for my application to wait a full second for all the threads to stop before it closed down on exit.
How responsive you need it to be is up to your application. The shorter the wake up times the more CPU it consumes. However even very short intervals of a few milliseconds will probably not register much in terms of CPU time.
add a comment |Â
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
How can I use an
std::condition_variableto wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same withoutcondition_variabletechnique?
No, not in standard C++ as of C++17 (there are of course non-standard, platform-specific ways to do it, and it's likely some kind of semaphore will be added to C++2a).
Additionally, I see that I need to use a
std::mutexin conjunction withstd::condition_variable? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variablelogic only to required places in the code piece here?
No. For a start, you can't wait on a condition_variable without locking a mutex (and passing the lock object to the wait function) so you need to have a mutex present anyway. Since you have to have a mutex anyway, requiring both the waiter and the notifier to use that mutex isn't such a big deal.
Condition variables are subject to "spurious wake ups" which means they can stop waiting for no reason. In order to tell if it woke because it was notified, or woke spuriously, you need some state variable that is set by the notifying thread and read by the waiting thread. Because that variable is shared by multiple threads it needs to be accessed safely, which the mutex ensures.
Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications.
This is all explained in more detail in
https://github.com/isocpp/CppCoreGuidelines/issues/554
1
"Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
â François Andrieux
1 hour ago
add a comment |Â
up vote
4
down vote
How can I use an
std::condition_variableto wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same withoutcondition_variabletechnique?
No, not in standard C++ as of C++17 (there are of course non-standard, platform-specific ways to do it, and it's likely some kind of semaphore will be added to C++2a).
Additionally, I see that I need to use a
std::mutexin conjunction withstd::condition_variable? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variablelogic only to required places in the code piece here?
No. For a start, you can't wait on a condition_variable without locking a mutex (and passing the lock object to the wait function) so you need to have a mutex present anyway. Since you have to have a mutex anyway, requiring both the waiter and the notifier to use that mutex isn't such a big deal.
Condition variables are subject to "spurious wake ups" which means they can stop waiting for no reason. In order to tell if it woke because it was notified, or woke spuriously, you need some state variable that is set by the notifying thread and read by the waiting thread. Because that variable is shared by multiple threads it needs to be accessed safely, which the mutex ensures.
Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications.
This is all explained in more detail in
https://github.com/isocpp/CppCoreGuidelines/issues/554
1
"Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
â François Andrieux
1 hour ago
add a comment |Â
up vote
4
down vote
up vote
4
down vote
How can I use an
std::condition_variableto wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same withoutcondition_variabletechnique?
No, not in standard C++ as of C++17 (there are of course non-standard, platform-specific ways to do it, and it's likely some kind of semaphore will be added to C++2a).
Additionally, I see that I need to use a
std::mutexin conjunction withstd::condition_variable? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variablelogic only to required places in the code piece here?
No. For a start, you can't wait on a condition_variable without locking a mutex (and passing the lock object to the wait function) so you need to have a mutex present anyway. Since you have to have a mutex anyway, requiring both the waiter and the notifier to use that mutex isn't such a big deal.
Condition variables are subject to "spurious wake ups" which means they can stop waiting for no reason. In order to tell if it woke because it was notified, or woke spuriously, you need some state variable that is set by the notifying thread and read by the waiting thread. Because that variable is shared by multiple threads it needs to be accessed safely, which the mutex ensures.
Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications.
This is all explained in more detail in
https://github.com/isocpp/CppCoreGuidelines/issues/554
How can I use an
std::condition_variableto wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same withoutcondition_variabletechnique?
No, not in standard C++ as of C++17 (there are of course non-standard, platform-specific ways to do it, and it's likely some kind of semaphore will be added to C++2a).
Additionally, I see that I need to use a
std::mutexin conjunction withstd::condition_variable? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variablelogic only to required places in the code piece here?
No. For a start, you can't wait on a condition_variable without locking a mutex (and passing the lock object to the wait function) so you need to have a mutex present anyway. Since you have to have a mutex anyway, requiring both the waiter and the notifier to use that mutex isn't such a big deal.
Condition variables are subject to "spurious wake ups" which means they can stop waiting for no reason. In order to tell if it woke because it was notified, or woke spuriously, you need some state variable that is set by the notifying thread and read by the waiting thread. Because that variable is shared by multiple threads it needs to be accessed safely, which the mutex ensures.
Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications.
This is all explained in more detail in
https://github.com/isocpp/CppCoreGuidelines/issues/554
answered 1 hour ago
Jonathan Wakely
127k14231392
127k14231392
1
"Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
â François Andrieux
1 hour ago
add a comment |Â
1
"Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
â François Andrieux
1 hour ago
1
1
"Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
â François Andrieux
1 hour ago
"Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
â François Andrieux
1 hour ago
add a comment |Â
up vote
2
down vote
There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.
Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.
Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.
Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.
add a comment |Â
up vote
2
down vote
There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.
Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.
Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.
Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.
Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.
Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.
Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.
There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.
Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.
Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.
Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.
answered 1 hour ago
SergeyA
38.2k53477
38.2k53477
add a comment |Â
add a comment |Â
up vote
2
down vote
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?
You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.
add a comment |Â
up vote
2
down vote
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?
You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?
You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.
How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?
You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.
answered 1 hour ago
Slava
30.9k12659
30.9k12659
add a comment |Â
add a comment |Â
up vote
1
down vote
A working example for you using std::condition_variable:
struct MyClass
MyClass()
: my_thread([this]() this->thread(); )
~MyClass()
std::lock_guard<std::mutex> l(m_);
stop_ = true;
c_.notify_one();
my_thread.join();
void thread()
for(;;)
std::unique_lock<std::mutex> l(m_);
if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
return; // stop_ == true.
SendStatusInfo(some_info);
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
add a comment |Â
up vote
1
down vote
A working example for you using std::condition_variable:
struct MyClass
MyClass()
: my_thread([this]() this->thread(); )
~MyClass()
std::lock_guard<std::mutex> l(m_);
stop_ = true;
c_.notify_one();
my_thread.join();
void thread()
for(;;)
std::unique_lock<std::mutex> l(m_);
if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
return; // stop_ == true.
SendStatusInfo(some_info);
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
add a comment |Â
up vote
1
down vote
up vote
1
down vote
A working example for you using std::condition_variable:
struct MyClass
MyClass()
: my_thread([this]() this->thread(); )
~MyClass()
std::lock_guard<std::mutex> l(m_);
stop_ = true;
c_.notify_one();
my_thread.join();
void thread()
for(;;)
std::unique_lock<std::mutex> l(m_);
if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
return; // stop_ == true.
SendStatusInfo(some_info);
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
A working example for you using std::condition_variable:
struct MyClass
MyClass()
: my_thread([this]() this->thread(); )
~MyClass()
std::lock_guard<std::mutex> l(m_);
stop_ = true;
c_.notify_one();
my_thread.join();
void thread()
for(;;)
std::unique_lock<std::mutex> l(m_);
if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
return; // stop_ == true.
SendStatusInfo(some_info);
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
answered 1 hour ago
Maxim Egorushkin
81k1195177
81k1195177
add a comment |Â
add a comment |Â
up vote
0
down vote
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.
struct timed_waiter
void interrupt()
auto l = lock();
interrupted = true;
cv.notify_all();
// returns false if interrupted
template<class Rep, class Period>
bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
auto l = lock();
return !cv.wait_until( l,
std::chrono::steady_clock::now() + how_long,
[&]
return !interrupted;
);
private:
std::unique_lock<std::mutex> lock() const
return std::unique_lock<std::mutex>(m);
mutable std::mutex m;
mutable std::condition_variable cv;
bool interrupted = false;
;
simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.
The waiting threads do
while(m_timer.wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.
Live example:
struct MyClass
~MyClass();
void RunMyThread();
private:
std::thread my_thread;
timed_waiter m_timer;
;
void MyClass::RunMyThread()
my_thread = std::thread
[this]
while(m_timer.wait_for(std::chrono::seconds(2)))
std::cout << "SendStatusInfo(some_info)n";
;
// Destructor
MyClass::~MyClass()
std::cout << "~MyClass::MyClassn";
m_timer.interrupt();
my_thread.join();
std::cout << "~MyClass::MyClass donen";
int main()
std::cout << "start of mainn";
MyClass x;
x.RunMyThread();
using namespace std::literals;
std::this_thread::sleep_for(11s);
std::cout << "end of mainn";
add a comment |Â
up vote
0
down vote
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.
struct timed_waiter
void interrupt()
auto l = lock();
interrupted = true;
cv.notify_all();
// returns false if interrupted
template<class Rep, class Period>
bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
auto l = lock();
return !cv.wait_until( l,
std::chrono::steady_clock::now() + how_long,
[&]
return !interrupted;
);
private:
std::unique_lock<std::mutex> lock() const
return std::unique_lock<std::mutex>(m);
mutable std::mutex m;
mutable std::condition_variable cv;
bool interrupted = false;
;
simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.
The waiting threads do
while(m_timer.wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.
Live example:
struct MyClass
~MyClass();
void RunMyThread();
private:
std::thread my_thread;
timed_waiter m_timer;
;
void MyClass::RunMyThread()
my_thread = std::thread
[this]
while(m_timer.wait_for(std::chrono::seconds(2)))
std::cout << "SendStatusInfo(some_info)n";
;
// Destructor
MyClass::~MyClass()
std::cout << "~MyClass::MyClassn";
m_timer.interrupt();
my_thread.join();
std::cout << "~MyClass::MyClass donen";
int main()
std::cout << "start of mainn";
MyClass x;
x.RunMyThread();
using namespace std::literals;
std::this_thread::sleep_for(11s);
std::cout << "end of mainn";
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.
struct timed_waiter
void interrupt()
auto l = lock();
interrupted = true;
cv.notify_all();
// returns false if interrupted
template<class Rep, class Period>
bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
auto l = lock();
return !cv.wait_until( l,
std::chrono::steady_clock::now() + how_long,
[&]
return !interrupted;
);
private:
std::unique_lock<std::mutex> lock() const
return std::unique_lock<std::mutex>(m);
mutable std::mutex m;
mutable std::condition_variable cv;
bool interrupted = false;
;
simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.
The waiting threads do
while(m_timer.wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.
Live example:
struct MyClass
~MyClass();
void RunMyThread();
private:
std::thread my_thread;
timed_waiter m_timer;
;
void MyClass::RunMyThread()
my_thread = std::thread
[this]
while(m_timer.wait_for(std::chrono::seconds(2)))
std::cout << "SendStatusInfo(some_info)n";
;
// Destructor
MyClass::~MyClass()
std::cout << "~MyClass::MyClassn";
m_timer.interrupt();
my_thread.join();
std::cout << "~MyClass::MyClass donen";
int main()
std::cout << "start of mainn";
MyClass x;
x.RunMyThread();
using namespace std::literals;
std::this_thread::sleep_for(11s);
std::cout << "end of mainn";
Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?
std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.
struct timed_waiter
void interrupt()
auto l = lock();
interrupted = true;
cv.notify_all();
// returns false if interrupted
template<class Rep, class Period>
bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
auto l = lock();
return !cv.wait_until( l,
std::chrono::steady_clock::now() + how_long,
[&]
return !interrupted;
);
private:
std::unique_lock<std::mutex> lock() const
return std::unique_lock<std::mutex>(m);
mutable std::mutex m;
mutable std::condition_variable cv;
bool interrupted = false;
;
simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.
The waiting threads do
while(m_timer.wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.
Live example:
struct MyClass
~MyClass();
void RunMyThread();
private:
std::thread my_thread;
timed_waiter m_timer;
;
void MyClass::RunMyThread()
my_thread = std::thread
[this]
while(m_timer.wait_for(std::chrono::seconds(2)))
std::cout << "SendStatusInfo(some_info)n";
;
// Destructor
MyClass::~MyClass()
std::cout << "~MyClass::MyClassn";
m_timer.interrupt();
my_thread.join();
std::cout << "~MyClass::MyClass donen";
int main()
std::cout << "start of mainn";
MyClass x;
x.RunMyThread();
using namespace std::literals;
std::this_thread::sleep_for(11s);
std::cout << "end of mainn";
edited 58 mins ago
answered 1 hour ago
Yakk - Adam Nevraumont
172k18175354
172k18175354
add a comment |Â
add a comment |Â
up vote
0
down vote
Or are there any other ways of achieving the same without condition_variable technique?
One alternative to a condition variable is you can wake your thread up at much more regular intervals to check the "running" flag and go back to sleep if it is not set and the allotted time has not yet expired:
void periodically_call(std::atomic_bool& running, std::chrono::milliseconds wait_time)
auto wake_up = std::chrono::steady_clock::now();
while(running)
wake_up += wait_time; // next signal send time
while(std::chrono::steady_clock::now() < wake_up)
if(!running)
break;
// sleep for just 1/10 sec (maximum)
auto pre_wake_up = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
pre_wake_up = std::min(wake_up, pre_wake_up); // don't overshoot
// keep going to sleep here until full time
// has expired
std::this_thread::sleep_until(pre_wake_up);
SendStatusInfo(some_info); // do the regular call
Note: You can make the actual wait time anything you want. In this example I made it 100ms std::chrono::milliseconds(100). It depends how responsive you want your thread to be to a signal to stop.
For example in one application I made that one whole second because I was happy for my application to wait a full second for all the threads to stop before it closed down on exit.
How responsive you need it to be is up to your application. The shorter the wake up times the more CPU it consumes. However even very short intervals of a few milliseconds will probably not register much in terms of CPU time.
add a comment |Â
up vote
0
down vote
Or are there any other ways of achieving the same without condition_variable technique?
One alternative to a condition variable is you can wake your thread up at much more regular intervals to check the "running" flag and go back to sleep if it is not set and the allotted time has not yet expired:
void periodically_call(std::atomic_bool& running, std::chrono::milliseconds wait_time)
auto wake_up = std::chrono::steady_clock::now();
while(running)
wake_up += wait_time; // next signal send time
while(std::chrono::steady_clock::now() < wake_up)
if(!running)
break;
// sleep for just 1/10 sec (maximum)
auto pre_wake_up = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
pre_wake_up = std::min(wake_up, pre_wake_up); // don't overshoot
// keep going to sleep here until full time
// has expired
std::this_thread::sleep_until(pre_wake_up);
SendStatusInfo(some_info); // do the regular call
Note: You can make the actual wait time anything you want. In this example I made it 100ms std::chrono::milliseconds(100). It depends how responsive you want your thread to be to a signal to stop.
For example in one application I made that one whole second because I was happy for my application to wait a full second for all the threads to stop before it closed down on exit.
How responsive you need it to be is up to your application. The shorter the wake up times the more CPU it consumes. However even very short intervals of a few milliseconds will probably not register much in terms of CPU time.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Or are there any other ways of achieving the same without condition_variable technique?
One alternative to a condition variable is you can wake your thread up at much more regular intervals to check the "running" flag and go back to sleep if it is not set and the allotted time has not yet expired:
void periodically_call(std::atomic_bool& running, std::chrono::milliseconds wait_time)
auto wake_up = std::chrono::steady_clock::now();
while(running)
wake_up += wait_time; // next signal send time
while(std::chrono::steady_clock::now() < wake_up)
if(!running)
break;
// sleep for just 1/10 sec (maximum)
auto pre_wake_up = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
pre_wake_up = std::min(wake_up, pre_wake_up); // don't overshoot
// keep going to sleep here until full time
// has expired
std::this_thread::sleep_until(pre_wake_up);
SendStatusInfo(some_info); // do the regular call
Note: You can make the actual wait time anything you want. In this example I made it 100ms std::chrono::milliseconds(100). It depends how responsive you want your thread to be to a signal to stop.
For example in one application I made that one whole second because I was happy for my application to wait a full second for all the threads to stop before it closed down on exit.
How responsive you need it to be is up to your application. The shorter the wake up times the more CPU it consumes. However even very short intervals of a few milliseconds will probably not register much in terms of CPU time.
Or are there any other ways of achieving the same without condition_variable technique?
One alternative to a condition variable is you can wake your thread up at much more regular intervals to check the "running" flag and go back to sleep if it is not set and the allotted time has not yet expired:
void periodically_call(std::atomic_bool& running, std::chrono::milliseconds wait_time)
auto wake_up = std::chrono::steady_clock::now();
while(running)
wake_up += wait_time; // next signal send time
while(std::chrono::steady_clock::now() < wake_up)
if(!running)
break;
// sleep for just 1/10 sec (maximum)
auto pre_wake_up = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
pre_wake_up = std::min(wake_up, pre_wake_up); // don't overshoot
// keep going to sleep here until full time
// has expired
std::this_thread::sleep_until(pre_wake_up);
SendStatusInfo(some_info); // do the regular call
Note: You can make the actual wait time anything you want. In this example I made it 100ms std::chrono::milliseconds(100). It depends how responsive you want your thread to be to a signal to stop.
For example in one application I made that one whole second because I was happy for my application to wait a full second for all the threads to stop before it closed down on exit.
How responsive you need it to be is up to your application. The shorter the wake up times the more CPU it consumes. However even very short intervals of a few milliseconds will probably not register much in terms of CPU time.
edited 35 mins ago
answered 43 mins ago
Galik
32k34673
32k34673
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52610776%2fhow-to-wake-an-stdthread-while-it-is-sleeping%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password

Note that the code you've shown is full of syntax errors.
â François Andrieux
1 hour ago
Remember to
jointhestd::threadin the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.â François Andrieux
1 hour ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
1 hour ago