How to wake a std::thread while it is sleeping
Clash Royale CLAN TAG#URR8PPP
up vote
8
down vote
favorite
I am using C++11 and I have a std::thread
which is a class member, and it sends information to listeners every 2 minutes. Other that that it just sleeps. So, I have made it sleep for 2 minutes, then send the required info, and then sleep for 2 minutes again.
// MyClass.hpp
class 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 I've found look too complex for what I am trying to do here.
Question:
How can I use a std::condition_variable
to wake the thread and exit gracefully while it is sleeping? Or are there any other ways of achieving the same without the 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 here?
Environment:
Linux and Unix with compilers gcc and clang.
c++ c++11 mutex condition-variable stdthread
 |Â
show 1 more comment
up vote
8
down vote
favorite
I am using C++11 and I have a std::thread
which is a class member, and it sends information to listeners every 2 minutes. Other that that it just sleeps. So, I have made it sleep for 2 minutes, then send the required info, and then sleep for 2 minutes again.
// MyClass.hpp
class 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 I've found look too complex for what I am trying to do here.
Question:
How can I use a std::condition_variable
to wake the thread and exit gracefully while it is sleeping? Or are there any other ways of achieving the same without the 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 here?
Environment:
Linux and Unix with compilers gcc and clang.
c++ c++11 mutex condition-variable stdthread
1
Note that the code you've shown is full of syntax errors.
â François Andrieux
10 hours ago
Remember tojoin
thestd::thread
in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
â François Andrieux
10 hours ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
10 hours ago
2
As an alternative tostd::condition_variable
- for a case like this where you need a one-time signal, you could usestd::promise<void>
andstd::future::wait_for()
â Daniel Schepler
7 hours ago
@PaulSanders My code needs to run on linux and unix. I updated the question with details of the dev environment
â Game_Of_Threads
7 hours ago
 |Â
show 1 more comment
up vote
8
down vote
favorite
up vote
8
down vote
favorite
I am using C++11 and I have a std::thread
which is a class member, and it sends information to listeners every 2 minutes. Other that that it just sleeps. So, I have made it sleep for 2 minutes, then send the required info, and then sleep for 2 minutes again.
// MyClass.hpp
class 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 I've found look too complex for what I am trying to do here.
Question:
How can I use a std::condition_variable
to wake the thread and exit gracefully while it is sleeping? Or are there any other ways of achieving the same without the 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 here?
Environment:
Linux and Unix with compilers gcc and clang.
c++ c++11 mutex condition-variable stdthread
I am using C++11 and I have a std::thread
which is a class member, and it sends information to listeners every 2 minutes. Other that that it just sleeps. So, I have made it sleep for 2 minutes, then send the required info, and then sleep for 2 minutes again.
// MyClass.hpp
class 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 I've found look too complex for what I am trying to do here.
Question:
How can I use a std::condition_variable
to wake the thread and exit gracefully while it is sleeping? Or are there any other ways of achieving the same without the 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 here?
Environment:
Linux and Unix with compilers gcc and clang.
c++ c++11 mutex condition-variable stdthread
c++ c++11 mutex condition-variable stdthread
edited 5 mins ago
Pharap
2,06312132
2,06312132
asked 10 hours ago
Game_Of_Threads
1,37511138
1,37511138
1
Note that the code you've shown is full of syntax errors.
â François Andrieux
10 hours ago
Remember tojoin
thestd::thread
in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
â François Andrieux
10 hours ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
10 hours ago
2
As an alternative tostd::condition_variable
- for a case like this where you need a one-time signal, you could usestd::promise<void>
andstd::future::wait_for()
â Daniel Schepler
7 hours ago
@PaulSanders My code needs to run on linux and unix. I updated the question with details of the dev environment
â Game_Of_Threads
7 hours ago
 |Â
show 1 more comment
1
Note that the code you've shown is full of syntax errors.
â François Andrieux
10 hours ago
Remember tojoin
thestd::thread
in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
â François Andrieux
10 hours ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
10 hours ago
2
As an alternative tostd::condition_variable
- for a case like this where you need a one-time signal, you could usestd::promise<void>
andstd::future::wait_for()
â Daniel Schepler
7 hours ago
@PaulSanders My code needs to run on linux and unix. I updated the question with details of the dev environment
â Game_Of_Threads
7 hours ago
1
1
Note that the code you've shown is full of syntax errors.
â François Andrieux
10 hours ago
Note that the code you've shown is full of syntax errors.
â François Andrieux
10 hours 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
10 hours 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
10 hours ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
10 hours ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
10 hours ago
2
2
As an alternative to
std::condition_variable
- for a case like this where you need a one-time signal, you could use std::promise<void>
and std::future::wait_for()
â Daniel Schepler
7 hours ago
As an alternative to
std::condition_variable
- for a case like this where you need a one-time signal, you could use std::promise<void>
and std::future::wait_for()
â Daniel Schepler
7 hours ago
@PaulSanders My code needs to run on linux and unix. I updated the question with details of the dev environment
â Game_Of_Threads
7 hours ago
@PaulSanders My code needs to run on linux and unix. I updated the question with details of the dev environment
â Game_Of_Threads
7 hours ago
 |Â
show 1 more comment
8 Answers
8
active
oldest
votes
up vote
11
down vote
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 withoutcondition_variable
technique?
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::mutex
in conjunction withstd::condition_variable
? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variable
logic 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
2
"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
10 hours ago
What does it mean a "spurios wake up"? I've never heard of this. Wouldn't such a thing make acondition_variable
pointless?
â Bakuriu
5 hours ago
See en.wikipedia.org/wiki/Spurious_wakeup -- and no, it doesn't make it pointless, because everything works fine as long as you use a condition variable correctly (by associating it with an actual condition such as "the shared variable is non-zero" and using a mutex to synchronise access to the shared variable and to prevent missed notifications).
â Jonathan Wakely
5 hours ago
add a comment |Â
up vote
6
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.
std::condition_variable::wait_for()
. I think this might be what I need.
â Game_Of_Threads
8 hours ago
add a comment |Â
up vote
4
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.
Ah this is posix constraint then. Unfortunately I have stay within realms of C++ only. Seems like my question somehow did not set the point correctly that as part of answer, I am looking for a code modification of the sample I provided. but never-mind. I am looking to try thestd::condition_variable::wait_for()
as indicated in the answer from Siava.
â Game_Of_Threads
8 hours ago
Very interesting fundamental facts. At least I am now sure about some of the things I was guessing looking at all condition_var examples around
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
4
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()
while(this->wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
// Returns false if stop_ == true.
template<class Duration>
bool wait_for(Duration duration)
std::unique_lock<std::mutex> l(m_);
return !c_.wait_for(l, duration, [this]() return stop_; );
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
l
does not need to be locked and unlocked? its simpler if it doesnt need to but probably it needs to be?
â Game_Of_Threads
7 hours ago
1
@Game_Of_Threads No. Read the documentation carefully: en.cppreference.com/w/cpp/thread/condition_variable/wait_for
â Maxim Egorushkin
7 hours ago
1
Ok. I get it now. the lock is more like mandatory for condition variable since it itself locks and releases in required conditions. Thanks @Maxim Egorushkin
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
1
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 |Â
up vote
-1
down vote
You can use std::promise/std::future as a simpler alternative to a bool
/condition_variable
/mutex
in this case. A future
is not susceptible to spurious wakes and doesn't require a mutex
for synchronisation.
Basic example:
std::promise<void> pr;
std::thread thr[fut = pr.get_future()]
while(true)
if(fut.wait_for(2min) != future_status::timeout)
return;
;
//When ready to stop
pr.set_value();
thr.join();
add a comment |Â
up vote
-1
down vote
You could also use promise/future so that you don't need to bother with conditionnal and/or threads:
#include <future>
#include <iostream>
struct MyClass
~MyClass()
_stop.set_value();
MyClass()
auto future = std::shared_future<void>(_stop.get_future());
_thread_handle = std::async(std::launch::async, [future] ()
std::future_status status;
do
status = future.wait_for(std::chrono::seconds(2));
if (status == std::future_status::timeout)
std::cout << "do periodic thingsn";
else if (status == std::future_status::ready)
std::cout << "exitingn";
while (status != std::future_status::ready);
);
private:
std::promise<void> _stop;
std::future<void> _thread_handle;
;
// Destructor
int main()
MyClass c;
std::this_thread::sleep_for(std::chrono::seconds(9));
add a comment |Â
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
11
down vote
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 withoutcondition_variable
technique?
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::mutex
in conjunction withstd::condition_variable
? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variable
logic 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
2
"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
10 hours ago
What does it mean a "spurios wake up"? I've never heard of this. Wouldn't such a thing make acondition_variable
pointless?
â Bakuriu
5 hours ago
See en.wikipedia.org/wiki/Spurious_wakeup -- and no, it doesn't make it pointless, because everything works fine as long as you use a condition variable correctly (by associating it with an actual condition such as "the shared variable is non-zero" and using a mutex to synchronise access to the shared variable and to prevent missed notifications).
â Jonathan Wakely
5 hours ago
add a comment |Â
up vote
11
down vote
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 withoutcondition_variable
technique?
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::mutex
in conjunction withstd::condition_variable
? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variable
logic 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
2
"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
10 hours ago
What does it mean a "spurios wake up"? I've never heard of this. Wouldn't such a thing make acondition_variable
pointless?
â Bakuriu
5 hours ago
See en.wikipedia.org/wiki/Spurious_wakeup -- and no, it doesn't make it pointless, because everything works fine as long as you use a condition variable correctly (by associating it with an actual condition such as "the shared variable is non-zero" and using a mutex to synchronise access to the shared variable and to prevent missed notifications).
â Jonathan Wakely
5 hours ago
add a comment |Â
up vote
11
down vote
up vote
11
down vote
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 withoutcondition_variable
technique?
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::mutex
in conjunction withstd::condition_variable
? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variable
logic 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_variable
to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same withoutcondition_variable
technique?
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::mutex
in conjunction withstd::condition_variable
? Is that really necessary?
Yes.
Is it not possible to achieve the goal by adding the
std::condition_variable
logic 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 10 hours ago
Jonathan Wakely
127k14231393
127k14231393
2
"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
10 hours ago
What does it mean a "spurios wake up"? I've never heard of this. Wouldn't such a thing make acondition_variable
pointless?
â Bakuriu
5 hours ago
See en.wikipedia.org/wiki/Spurious_wakeup -- and no, it doesn't make it pointless, because everything works fine as long as you use a condition variable correctly (by associating it with an actual condition such as "the shared variable is non-zero" and using a mutex to synchronise access to the shared variable and to prevent missed notifications).
â Jonathan Wakely
5 hours ago
add a comment |Â
2
"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
10 hours ago
What does it mean a "spurios wake up"? I've never heard of this. Wouldn't such a thing make acondition_variable
pointless?
â Bakuriu
5 hours ago
See en.wikipedia.org/wiki/Spurious_wakeup -- and no, it doesn't make it pointless, because everything works fine as long as you use a condition variable correctly (by associating it with an actual condition such as "the shared variable is non-zero" and using a mutex to synchronise access to the shared variable and to prevent missed notifications).
â Jonathan Wakely
5 hours ago
2
2
"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
10 hours 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
10 hours ago
What does it mean a "spurios wake up"? I've never heard of this. Wouldn't such a thing make a
condition_variable
pointless?â Bakuriu
5 hours ago
What does it mean a "spurios wake up"? I've never heard of this. Wouldn't such a thing make a
condition_variable
pointless?â Bakuriu
5 hours ago
See en.wikipedia.org/wiki/Spurious_wakeup -- and no, it doesn't make it pointless, because everything works fine as long as you use a condition variable correctly (by associating it with an actual condition such as "the shared variable is non-zero" and using a mutex to synchronise access to the shared variable and to prevent missed notifications).
â Jonathan Wakely
5 hours ago
See en.wikipedia.org/wiki/Spurious_wakeup -- and no, it doesn't make it pointless, because everything works fine as long as you use a condition variable correctly (by associating it with an actual condition such as "the shared variable is non-zero" and using a mutex to synchronise access to the shared variable and to prevent missed notifications).
â Jonathan Wakely
5 hours ago
add a comment |Â
up vote
6
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.
std::condition_variable::wait_for()
. I think this might be what I need.
â Game_Of_Threads
8 hours ago
add a comment |Â
up vote
6
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.
std::condition_variable::wait_for()
. I think this might be what I need.
â Game_Of_Threads
8 hours ago
add a comment |Â
up vote
6
down vote
up vote
6
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 10 hours ago
Slava
31k12659
31k12659
std::condition_variable::wait_for()
. I think this might be what I need.
â Game_Of_Threads
8 hours ago
add a comment |Â
std::condition_variable::wait_for()
. I think this might be what I need.
â Game_Of_Threads
8 hours ago
std::condition_variable::wait_for()
. I think this might be what I need.â Game_Of_Threads
8 hours ago
std::condition_variable::wait_for()
. I think this might be what I need.â Game_Of_Threads
8 hours ago
add a comment |Â
up vote
4
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.
Ah this is posix constraint then. Unfortunately I have stay within realms of C++ only. Seems like my question somehow did not set the point correctly that as part of answer, I am looking for a code modification of the sample I provided. but never-mind. I am looking to try thestd::condition_variable::wait_for()
as indicated in the answer from Siava.
â Game_Of_Threads
8 hours ago
Very interesting fundamental facts. At least I am now sure about some of the things I was guessing looking at all condition_var examples around
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
4
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.
Ah this is posix constraint then. Unfortunately I have stay within realms of C++ only. Seems like my question somehow did not set the point correctly that as part of answer, I am looking for a code modification of the sample I provided. but never-mind. I am looking to try thestd::condition_variable::wait_for()
as indicated in the answer from Siava.
â Game_Of_Threads
8 hours ago
Very interesting fundamental facts. At least I am now sure about some of the things I was guessing looking at all condition_var examples around
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
4
down vote
up vote
4
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 10 hours ago
SergeyA
38.2k53477
38.2k53477
Ah this is posix constraint then. Unfortunately I have stay within realms of C++ only. Seems like my question somehow did not set the point correctly that as part of answer, I am looking for a code modification of the sample I provided. but never-mind. I am looking to try thestd::condition_variable::wait_for()
as indicated in the answer from Siava.
â Game_Of_Threads
8 hours ago
Very interesting fundamental facts. At least I am now sure about some of the things I was guessing looking at all condition_var examples around
â Game_Of_Threads
7 hours ago
add a comment |Â
Ah this is posix constraint then. Unfortunately I have stay within realms of C++ only. Seems like my question somehow did not set the point correctly that as part of answer, I am looking for a code modification of the sample I provided. but never-mind. I am looking to try thestd::condition_variable::wait_for()
as indicated in the answer from Siava.
â Game_Of_Threads
8 hours ago
Very interesting fundamental facts. At least I am now sure about some of the things I was guessing looking at all condition_var examples around
â Game_Of_Threads
7 hours ago
Ah this is posix constraint then. Unfortunately I have stay within realms of C++ only. Seems like my question somehow did not set the point correctly that as part of answer, I am looking for a code modification of the sample I provided. but never-mind. I am looking to try the
std::condition_variable::wait_for()
as indicated in the answer from Siava.â Game_Of_Threads
8 hours ago
Ah this is posix constraint then. Unfortunately I have stay within realms of C++ only. Seems like my question somehow did not set the point correctly that as part of answer, I am looking for a code modification of the sample I provided. but never-mind. I am looking to try the
std::condition_variable::wait_for()
as indicated in the answer from Siava.â Game_Of_Threads
8 hours ago
Very interesting fundamental facts. At least I am now sure about some of the things I was guessing looking at all condition_var examples around
â Game_Of_Threads
7 hours ago
Very interesting fundamental facts. At least I am now sure about some of the things I was guessing looking at all condition_var examples around
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
4
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()
while(this->wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
// Returns false if stop_ == true.
template<class Duration>
bool wait_for(Duration duration)
std::unique_lock<std::mutex> l(m_);
return !c_.wait_for(l, duration, [this]() return stop_; );
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
l
does not need to be locked and unlocked? its simpler if it doesnt need to but probably it needs to be?
â Game_Of_Threads
7 hours ago
1
@Game_Of_Threads No. Read the documentation carefully: en.cppreference.com/w/cpp/thread/condition_variable/wait_for
â Maxim Egorushkin
7 hours ago
1
Ok. I get it now. the lock is more like mandatory for condition variable since it itself locks and releases in required conditions. Thanks @Maxim Egorushkin
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
4
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()
while(this->wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
// Returns false if stop_ == true.
template<class Duration>
bool wait_for(Duration duration)
std::unique_lock<std::mutex> l(m_);
return !c_.wait_for(l, duration, [this]() return stop_; );
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
l
does not need to be locked and unlocked? its simpler if it doesnt need to but probably it needs to be?
â Game_Of_Threads
7 hours ago
1
@Game_Of_Threads No. Read the documentation carefully: en.cppreference.com/w/cpp/thread/condition_variable/wait_for
â Maxim Egorushkin
7 hours ago
1
Ok. I get it now. the lock is more like mandatory for condition variable since it itself locks and releases in required conditions. Thanks @Maxim Egorushkin
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
4
down vote
up vote
4
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()
while(this->wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
// Returns false if stop_ == true.
template<class Duration>
bool wait_for(Duration duration)
std::unique_lock<std::mutex> l(m_);
return !c_.wait_for(l, duration, [this]() return stop_; );
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()
while(this->wait_for(std::chrono::minutes(2)))
SendStatusInfo(some_info);
// Returns false if stop_ == true.
template<class Duration>
bool wait_for(Duration duration)
std::unique_lock<std::mutex> l(m_);
return !c_.wait_for(l, duration, [this]() return stop_; );
std::condition_variable c_;
std::mutex m_;
bool stop_ = false;
std::thread my_thread;
;
edited 7 hours ago
answered 10 hours ago
Maxim Egorushkin
81k1195177
81k1195177
l
does not need to be locked and unlocked? its simpler if it doesnt need to but probably it needs to be?
â Game_Of_Threads
7 hours ago
1
@Game_Of_Threads No. Read the documentation carefully: en.cppreference.com/w/cpp/thread/condition_variable/wait_for
â Maxim Egorushkin
7 hours ago
1
Ok. I get it now. the lock is more like mandatory for condition variable since it itself locks and releases in required conditions. Thanks @Maxim Egorushkin
â Game_Of_Threads
7 hours ago
add a comment |Â
l
does not need to be locked and unlocked? its simpler if it doesnt need to but probably it needs to be?
â Game_Of_Threads
7 hours ago
1
@Game_Of_Threads No. Read the documentation carefully: en.cppreference.com/w/cpp/thread/condition_variable/wait_for
â Maxim Egorushkin
7 hours ago
1
Ok. I get it now. the lock is more like mandatory for condition variable since it itself locks and releases in required conditions. Thanks @Maxim Egorushkin
â Game_Of_Threads
7 hours ago
l
does not need to be locked and unlocked? its simpler if it doesnt need to but probably it needs to be?â Game_Of_Threads
7 hours ago
l
does not need to be locked and unlocked? its simpler if it doesnt need to but probably it needs to be?â Game_Of_Threads
7 hours ago
1
1
@Game_Of_Threads No. Read the documentation carefully: en.cppreference.com/w/cpp/thread/condition_variable/wait_for
â Maxim Egorushkin
7 hours ago
@Game_Of_Threads No. Read the documentation carefully: en.cppreference.com/w/cpp/thread/condition_variable/wait_for
â Maxim Egorushkin
7 hours ago
1
1
Ok. I get it now. the lock is more like mandatory for condition variable since it itself locks and releases in required conditions. Thanks @Maxim Egorushkin
â Game_Of_Threads
7 hours ago
Ok. I get it now. the lock is more like mandatory for condition variable since it itself locks and releases in required conditions. Thanks @Maxim Egorushkin
â Game_Of_Threads
7 hours ago
add a comment |Â
up vote
1
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
1
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
1
down vote
up vote
1
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 9 hours ago
answered 9 hours 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 9 hours ago
answered 9 hours ago
Galik
32k34673
32k34673
add a comment |Â
add a comment |Â
up vote
-1
down vote
You can use std::promise/std::future as a simpler alternative to a bool
/condition_variable
/mutex
in this case. A future
is not susceptible to spurious wakes and doesn't require a mutex
for synchronisation.
Basic example:
std::promise<void> pr;
std::thread thr[fut = pr.get_future()]
while(true)
if(fut.wait_for(2min) != future_status::timeout)
return;
;
//When ready to stop
pr.set_value();
thr.join();
add a comment |Â
up vote
-1
down vote
You can use std::promise/std::future as a simpler alternative to a bool
/condition_variable
/mutex
in this case. A future
is not susceptible to spurious wakes and doesn't require a mutex
for synchronisation.
Basic example:
std::promise<void> pr;
std::thread thr[fut = pr.get_future()]
while(true)
if(fut.wait_for(2min) != future_status::timeout)
return;
;
//When ready to stop
pr.set_value();
thr.join();
add a comment |Â
up vote
-1
down vote
up vote
-1
down vote
You can use std::promise/std::future as a simpler alternative to a bool
/condition_variable
/mutex
in this case. A future
is not susceptible to spurious wakes and doesn't require a mutex
for synchronisation.
Basic example:
std::promise<void> pr;
std::thread thr[fut = pr.get_future()]
while(true)
if(fut.wait_for(2min) != future_status::timeout)
return;
;
//When ready to stop
pr.set_value();
thr.join();
You can use std::promise/std::future as a simpler alternative to a bool
/condition_variable
/mutex
in this case. A future
is not susceptible to spurious wakes and doesn't require a mutex
for synchronisation.
Basic example:
std::promise<void> pr;
std::thread thr[fut = pr.get_future()]
while(true)
if(fut.wait_for(2min) != future_status::timeout)
return;
;
//When ready to stop
pr.set_value();
thr.join();
answered 6 hours ago
apophis42
93
93
add a comment |Â
add a comment |Â
up vote
-1
down vote
You could also use promise/future so that you don't need to bother with conditionnal and/or threads:
#include <future>
#include <iostream>
struct MyClass
~MyClass()
_stop.set_value();
MyClass()
auto future = std::shared_future<void>(_stop.get_future());
_thread_handle = std::async(std::launch::async, [future] ()
std::future_status status;
do
status = future.wait_for(std::chrono::seconds(2));
if (status == std::future_status::timeout)
std::cout << "do periodic thingsn";
else if (status == std::future_status::ready)
std::cout << "exitingn";
while (status != std::future_status::ready);
);
private:
std::promise<void> _stop;
std::future<void> _thread_handle;
;
// Destructor
int main()
MyClass c;
std::this_thread::sleep_for(std::chrono::seconds(9));
add a comment |Â
up vote
-1
down vote
You could also use promise/future so that you don't need to bother with conditionnal and/or threads:
#include <future>
#include <iostream>
struct MyClass
~MyClass()
_stop.set_value();
MyClass()
auto future = std::shared_future<void>(_stop.get_future());
_thread_handle = std::async(std::launch::async, [future] ()
std::future_status status;
do
status = future.wait_for(std::chrono::seconds(2));
if (status == std::future_status::timeout)
std::cout << "do periodic thingsn";
else if (status == std::future_status::ready)
std::cout << "exitingn";
while (status != std::future_status::ready);
);
private:
std::promise<void> _stop;
std::future<void> _thread_handle;
;
// Destructor
int main()
MyClass c;
std::this_thread::sleep_for(std::chrono::seconds(9));
add a comment |Â
up vote
-1
down vote
up vote
-1
down vote
You could also use promise/future so that you don't need to bother with conditionnal and/or threads:
#include <future>
#include <iostream>
struct MyClass
~MyClass()
_stop.set_value();
MyClass()
auto future = std::shared_future<void>(_stop.get_future());
_thread_handle = std::async(std::launch::async, [future] ()
std::future_status status;
do
status = future.wait_for(std::chrono::seconds(2));
if (status == std::future_status::timeout)
std::cout << "do periodic thingsn";
else if (status == std::future_status::ready)
std::cout << "exitingn";
while (status != std::future_status::ready);
);
private:
std::promise<void> _stop;
std::future<void> _thread_handle;
;
// Destructor
int main()
MyClass c;
std::this_thread::sleep_for(std::chrono::seconds(9));
You could also use promise/future so that you don't need to bother with conditionnal and/or threads:
#include <future>
#include <iostream>
struct MyClass
~MyClass()
_stop.set_value();
MyClass()
auto future = std::shared_future<void>(_stop.get_future());
_thread_handle = std::async(std::launch::async, [future] ()
std::future_status status;
do
status = future.wait_for(std::chrono::seconds(2));
if (status == std::future_status::timeout)
std::cout << "do periodic thingsn";
else if (status == std::future_status::ready)
std::cout << "exitingn";
while (status != std::future_status::ready);
);
private:
std::promise<void> _stop;
std::future<void> _thread_handle;
;
// Destructor
int main()
MyClass c;
std::this_thread::sleep_for(std::chrono::seconds(9));
answered 5 hours ago
OznOg
1,6451220
1,6451220
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-a-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
1
Note that the code you've shown is full of syntax errors.
â François Andrieux
10 hours ago
Remember to
join
thestd::thread
in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.â François Andrieux
10 hours ago
Are you on Windows? There are some OS primitives there that would help you.
â Paul Sanders
10 hours ago
2
As an alternative to
std::condition_variable
- for a case like this where you need a one-time signal, you could usestd::promise<void>
andstd::future::wait_for()
â Daniel Schepler
7 hours ago
@PaulSanders My code needs to run on linux and unix. I updated the question with details of the dev environment
â Game_Of_Threads
7 hours ago