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

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite
2












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.










share|improve this question



















  • 1




    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










  • 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 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














up vote
8
down vote

favorite
2












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.










share|improve this question



















  • 1




    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










  • 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 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












up vote
8
down vote

favorite
2









up vote
8
down vote

favorite
2






2





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.










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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






  • 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










  • @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




    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










  • 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 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







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












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 without condition_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 with std::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






share|improve this answer
















  • 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 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

















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.






share|improve this answer




















  • std::condition_variable::wait_for(). I think this might be what I need.
    – Game_Of_Threads
    8 hours ago

















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.






share|improve this answer




















  • 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


















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;
;





share|improve this answer






















  • 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

















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";






share|improve this answer





























    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.






    share|improve this answer





























      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();





      share|improve this answer



























        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));






        share|improve this answer




















          Your Answer





          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          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






























          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 without condition_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 with std::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






          share|improve this answer
















          • 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 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














          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 without condition_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 with std::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






          share|improve this answer
















          • 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 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












          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 without condition_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 with std::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






          share|improve this answer













          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?




          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 with std::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







          share|improve this answer












          share|improve this answer



          share|improve this answer










          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 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












          • 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 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







          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












          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.






          share|improve this answer




















          • std::condition_variable::wait_for(). I think this might be what I need.
            – Game_Of_Threads
            8 hours ago














          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.






          share|improve this answer




















          • std::condition_variable::wait_for(). I think this might be what I need.
            – Game_Of_Threads
            8 hours ago












          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.






          share|improve this answer













          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          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
















          • 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










          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.






          share|improve this answer




















          • 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















          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.






          share|improve this answer




















          • 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













          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.






          share|improve this answer












          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          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 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

















          • 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
















          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











          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;
          ;





          share|improve this answer






















          • 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














          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;
          ;





          share|improve this answer






















          • 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












          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;
          ;





          share|improve this answer














          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;
          ;






          share|improve this answer














          share|improve this answer



          share|improve this answer








          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
















          • 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










          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";






          share|improve this answer


























            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";






            share|improve this answer
























              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";






              share|improve this answer















              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";







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 9 hours ago

























              answered 9 hours ago









              Yakk - Adam Nevraumont

              172k18175354




              172k18175354




















                  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.






                  share|improve this answer


























                    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.






                    share|improve this answer
























                      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.






                      share|improve this answer















                      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.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 9 hours ago

























                      answered 9 hours ago









                      Galik

                      32k34673




                      32k34673




















                          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();





                          share|improve this answer
























                            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();





                            share|improve this answer






















                              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();





                              share|improve this answer












                              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();






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered 6 hours ago









                              apophis42

                              93




                              93




















                                  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));






                                  share|improve this answer
























                                    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));






                                    share|improve this answer






















                                      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));






                                      share|improve this answer












                                      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));







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered 5 hours ago









                                      OznOg

                                      1,6451220




                                      1,6451220



























                                           

                                          draft saved


                                          draft discarded















































                                           


                                          draft saved


                                          draft discarded














                                          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













































































                                          Comments

                                          Popular posts from this blog

                                          Long meetings (6-7 hours a day): Being “babysat” by supervisor

                                          Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                                          Confectionery