How to wake an 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
6
down vote

favorite












I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.



// MyClass.hpp
MyClass

~MyClass();
RunMyThread();

private:
std::thread my_thread;
std::atomic<bool> m_running;



MyClass::RunMyThread()

my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);

;


// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?



Issue:

The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.



Question:

How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?



Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?










share|improve this question























  • Note that the code you've shown is full of syntax errors.
    – François Andrieux
    1 hour ago










  • Remember to join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
    – François Andrieux
    1 hour ago










  • Are you on Windows? There are some OS primitives there that would help you.
    – Paul Sanders
    1 hour ago














up vote
6
down vote

favorite












I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.



// MyClass.hpp
MyClass

~MyClass();
RunMyThread();

private:
std::thread my_thread;
std::atomic<bool> m_running;



MyClass::RunMyThread()

my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);

;


// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?



Issue:

The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.



Question:

How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?



Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?










share|improve this question























  • Note that the code you've shown is full of syntax errors.
    – François Andrieux
    1 hour ago










  • Remember to join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
    – François Andrieux
    1 hour ago










  • Are you on Windows? There are some OS primitives there that would help you.
    – Paul Sanders
    1 hour ago












up vote
6
down vote

favorite









up vote
6
down vote

favorite











I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.



// MyClass.hpp
MyClass

~MyClass();
RunMyThread();

private:
std::thread my_thread;
std::atomic<bool> m_running;



MyClass::RunMyThread()

my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);

;


// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?



Issue:

The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.



Question:

How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?



Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?










share|improve this question















I am using C++ 11 and I have an std::thread which is a class member and it sends a necessary info piece to listeners in every 2 minutes. Other that that it just sleeps. So, I have made it to sleep for 2 minutes and then send the required info and then sleep for 2 minutes again.



// MyClass.hpp
MyClass

~MyClass();
RunMyThread();

private:
std::thread my_thread;
std::atomic<bool> m_running;



MyClass::RunMyThread()

my_thread = std::thread [this, m_running]
m_running = true;
while(m_running)
std::this_thread::sleep_for(std::chrono::minutes(2));
SendStatusInfo(some_info);

;


// Destructor
~MyClass::MyClass()
m_running = false; // this wont work as the thread is sleeping. How to exit thread here?



Issue:

The issue with this approach is that I cannot exit the thread while it is sleeping. I understand from reading that I can wake it using a std::condition_variable and exit gracefully? But I am struggling to find a simple example which does the bare minimum as required in above scenario. All the condition_variable examples around in C++ look too complex for such a simple thing that I am trying to do here.



Question:

How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping? Or are there any other ways of achieving the same without condition_variable technique?



Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?







c++ c++11 mutex condition-variable stdthread






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago

























asked 1 hour ago









Game_Of_Threads

1,36511138




1,36511138











  • Note that the code you've shown is full of syntax errors.
    – François Andrieux
    1 hour ago










  • Remember to join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
    – François Andrieux
    1 hour ago










  • Are you on Windows? There are some OS primitives there that would help you.
    – Paul Sanders
    1 hour ago
















  • Note that the code you've shown is full of syntax errors.
    – François Andrieux
    1 hour ago










  • Remember to join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
    – François Andrieux
    1 hour ago










  • Are you on Windows? There are some OS primitives there that would help you.
    – Paul Sanders
    1 hour ago















Note that the code you've shown is full of syntax errors.
– François Andrieux
1 hour ago




Note that the code you've shown is full of syntax errors.
– François Andrieux
1 hour ago












Remember to join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
– François Andrieux
1 hour ago




Remember to join the std::thread in the destructor. It's undefined behavior to destroy a thread that wasn't joined to detached.
– François Andrieux
1 hour ago












Are you on Windows? There are some OS primitives there that would help you.
– Paul Sanders
1 hour ago




Are you on Windows? There are some OS primitives there that would help you.
– Paul Sanders
1 hour ago












6 Answers
6






active

oldest

votes

















up vote
4
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
















  • 1




    "Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
    – François Andrieux
    1 hour ago


















up vote
2
down vote













There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.



Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.



Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.



Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.






share|improve this answer



























    up vote
    2
    down vote














    How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?




    You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()




    Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




    Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.






    share|improve this answer



























      up vote
      1
      down vote













      A working example for you using std::condition_variable:



      struct MyClass 
      MyClass()
      : my_thread([this]() this->thread(); )


      ~MyClass()

      std::lock_guard<std::mutex> l(m_);
      stop_ = true;

      c_.notify_one();
      my_thread.join();


      void thread()
      for(;;)

      std::unique_lock<std::mutex> l(m_);
      if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
      return; // stop_ == true.

      SendStatusInfo(some_info);



      std::condition_variable c_;
      std::mutex m_;
      bool stop_ = false;
      std::thread my_thread;
      ;





      share|improve this answer



























        up vote
        0
        down vote














        Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




        std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.



        struct timed_waiter 
        void interrupt()
        auto l = lock();
        interrupted = true;
        cv.notify_all();

        // returns false if interrupted
        template<class Rep, class Period>
        bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
        auto l = lock();
        return !cv.wait_until( l,
        std::chrono::steady_clock::now() + how_long,
        [&]
        return !interrupted;

        );

        private:
        std::unique_lock<std::mutex> lock() const
        return std::unique_lock<std::mutex>(m);

        mutable std::mutex m;
        mutable std::condition_variable cv;
        bool interrupted = false;
        ;


        simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.



        The waiting threads do



        while(m_timer.wait_for(std::chrono::minutes(2))) 
        SendStatusInfo(some_info);



        to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.



        Live example:



        struct MyClass 
        ~MyClass();
        void RunMyThread();
        private:
        std::thread my_thread;
        timed_waiter m_timer;
        ;


        void MyClass::RunMyThread()

        my_thread = std::thread
        [this]
        while(m_timer.wait_for(std::chrono::seconds(2)))
        std::cout << "SendStatusInfo(some_info)n";

        ;


        // Destructor
        MyClass::~MyClass()
        std::cout << "~MyClass::MyClassn";
        m_timer.interrupt();
        my_thread.join();
        std::cout << "~MyClass::MyClass donen";


        int main()
        std::cout << "start of mainn";

        MyClass x;
        x.RunMyThread();
        using namespace std::literals;
        std::this_thread::sleep_for(11s);

        std::cout << "end of mainn";






        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






















            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-an-stdthread-while-it-is-sleeping%23new-answer', 'question_page');

            );

            Post as a guest






























            6 Answers
            6






            active

            oldest

            votes








            6 Answers
            6






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            4
            down vote














            How can I use an std::condition_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
















            • 1




              "Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
              – François Andrieux
              1 hour ago















            up vote
            4
            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
















            • 1




              "Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
              – François Andrieux
              1 hour ago













            up vote
            4
            down vote










            up vote
            4
            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 1 hour ago









            Jonathan Wakely

            127k14231392




            127k14231392







            • 1




              "Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
              – François Andrieux
              1 hour ago













            • 1




              "Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
              – François Andrieux
              1 hour ago








            1




            1




            "Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
            – François Andrieux
            1 hour ago





            "Even if you use an atomic variable for the share variable, you still typically need a mutex to avoid missed notifications." is really what makes this the best answer. It's often assumed that you don't need a mutex if you have a thread-safe condition, which leads to terrible headaches. Edit : Seems like Slava's answer also mentions it.
            – François Andrieux
            1 hour ago













            up vote
            2
            down vote













            There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.



            Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.



            Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.



            Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.






            share|improve this answer
























              up vote
              2
              down vote













              There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.



              Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.



              Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.



              Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.






              share|improve this answer






















                up vote
                2
                down vote










                up vote
                2
                down vote









                There is a sad, but true fact - what you are looking for is a signal, and Posix threads do not have a true signalling mechanism.



                Also, the only Posix threading primitive associated with any sort of timing is conditional variable, this is why your online search lead you to it, and since C++ threading model is heavily built on Posix API, in standard C++ Posix-compatible primitives is all you get.



                Unless you are willing to go outside of Posix (you do not indicate platform, but there are native platform ways to work with events which are free from those limitations, notably eventfd in Linux) you will have to stick with condition variables and yes, working with condition variable requires a mutex, since it is built into API.



                Your question doesn't specifically ask for code sample, so I am not providing any. Let me know if you'd like some.






                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 1 hour ago









                SergeyA

                38.2k53477




                38.2k53477




















                    up vote
                    2
                    down vote














                    How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?




                    You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()




                    Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




                    Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.






                    share|improve this answer
























                      up vote
                      2
                      down vote














                      How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?




                      You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()




                      Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




                      Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.






                      share|improve this answer






















                        up vote
                        2
                        down vote










                        up vote
                        2
                        down vote










                        How can I use an std::condition_variable to wake the thread and exit gracefully while it was sleeping?




                        You use std::condition_variable::wait_for() instead of std::this_thread::sleep_for() and first one can be interrupted by std::condition_variable::notify_one() or std::condition_variable::notify_all()




                        Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




                        Yes it is necessary to use std::mutex with std::condition_variable and you should use it instead of making your flag std::atomic as despite atomicity of flag itself you would have race condition in your code and you will notice that sometimes your sleeping thread would miss notification if you would not use mutex here.






                        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 1 hour ago









                        Slava

                        30.9k12659




                        30.9k12659




















                            up vote
                            1
                            down vote













                            A working example for you using std::condition_variable:



                            struct MyClass 
                            MyClass()
                            : my_thread([this]() this->thread(); )


                            ~MyClass()

                            std::lock_guard<std::mutex> l(m_);
                            stop_ = true;

                            c_.notify_one();
                            my_thread.join();


                            void thread()
                            for(;;)

                            std::unique_lock<std::mutex> l(m_);
                            if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
                            return; // stop_ == true.

                            SendStatusInfo(some_info);



                            std::condition_variable c_;
                            std::mutex m_;
                            bool stop_ = false;
                            std::thread my_thread;
                            ;





                            share|improve this answer
























                              up vote
                              1
                              down vote













                              A working example for you using std::condition_variable:



                              struct MyClass 
                              MyClass()
                              : my_thread([this]() this->thread(); )


                              ~MyClass()

                              std::lock_guard<std::mutex> l(m_);
                              stop_ = true;

                              c_.notify_one();
                              my_thread.join();


                              void thread()
                              for(;;)

                              std::unique_lock<std::mutex> l(m_);
                              if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
                              return; // stop_ == true.

                              SendStatusInfo(some_info);



                              std::condition_variable c_;
                              std::mutex m_;
                              bool stop_ = false;
                              std::thread my_thread;
                              ;





                              share|improve this answer






















                                up vote
                                1
                                down vote










                                up vote
                                1
                                down vote









                                A working example for you using std::condition_variable:



                                struct MyClass 
                                MyClass()
                                : my_thread([this]() this->thread(); )


                                ~MyClass()

                                std::lock_guard<std::mutex> l(m_);
                                stop_ = true;

                                c_.notify_one();
                                my_thread.join();


                                void thread()
                                for(;;)

                                std::unique_lock<std::mutex> l(m_);
                                if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
                                return; // stop_ == true.

                                SendStatusInfo(some_info);



                                std::condition_variable c_;
                                std::mutex m_;
                                bool stop_ = false;
                                std::thread my_thread;
                                ;





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

                                std::unique_lock<std::mutex> l(m_);
                                if(c_.wait_for(l, std::chrono::minutes(2), [this]() return stop_; ))
                                return; // stop_ == true.

                                SendStatusInfo(some_info);



                                std::condition_variable c_;
                                std::mutex m_;
                                bool stop_ = false;
                                std::thread my_thread;
                                ;






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered 1 hour ago









                                Maxim Egorushkin

                                81k1195177




                                81k1195177




















                                    up vote
                                    0
                                    down vote














                                    Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




                                    std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.



                                    struct timed_waiter 
                                    void interrupt()
                                    auto l = lock();
                                    interrupted = true;
                                    cv.notify_all();

                                    // returns false if interrupted
                                    template<class Rep, class Period>
                                    bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
                                    auto l = lock();
                                    return !cv.wait_until( l,
                                    std::chrono::steady_clock::now() + how_long,
                                    [&]
                                    return !interrupted;

                                    );

                                    private:
                                    std::unique_lock<std::mutex> lock() const
                                    return std::unique_lock<std::mutex>(m);

                                    mutable std::mutex m;
                                    mutable std::condition_variable cv;
                                    bool interrupted = false;
                                    ;


                                    simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.



                                    The waiting threads do



                                    while(m_timer.wait_for(std::chrono::minutes(2))) 
                                    SendStatusInfo(some_info);



                                    to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.



                                    Live example:



                                    struct MyClass 
                                    ~MyClass();
                                    void RunMyThread();
                                    private:
                                    std::thread my_thread;
                                    timed_waiter m_timer;
                                    ;


                                    void MyClass::RunMyThread()

                                    my_thread = std::thread
                                    [this]
                                    while(m_timer.wait_for(std::chrono::seconds(2)))
                                    std::cout << "SendStatusInfo(some_info)n";

                                    ;


                                    // Destructor
                                    MyClass::~MyClass()
                                    std::cout << "~MyClass::MyClassn";
                                    m_timer.interrupt();
                                    my_thread.join();
                                    std::cout << "~MyClass::MyClass donen";


                                    int main()
                                    std::cout << "start of mainn";

                                    MyClass x;
                                    x.RunMyThread();
                                    using namespace std::literals;
                                    std::this_thread::sleep_for(11s);

                                    std::cout << "end of mainn";






                                    share|improve this answer


























                                      up vote
                                      0
                                      down vote














                                      Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




                                      std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.



                                      struct timed_waiter 
                                      void interrupt()
                                      auto l = lock();
                                      interrupted = true;
                                      cv.notify_all();

                                      // returns false if interrupted
                                      template<class Rep, class Period>
                                      bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
                                      auto l = lock();
                                      return !cv.wait_until( l,
                                      std::chrono::steady_clock::now() + how_long,
                                      [&]
                                      return !interrupted;

                                      );

                                      private:
                                      std::unique_lock<std::mutex> lock() const
                                      return std::unique_lock<std::mutex>(m);

                                      mutable std::mutex m;
                                      mutable std::condition_variable cv;
                                      bool interrupted = false;
                                      ;


                                      simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.



                                      The waiting threads do



                                      while(m_timer.wait_for(std::chrono::minutes(2))) 
                                      SendStatusInfo(some_info);



                                      to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.



                                      Live example:



                                      struct MyClass 
                                      ~MyClass();
                                      void RunMyThread();
                                      private:
                                      std::thread my_thread;
                                      timed_waiter m_timer;
                                      ;


                                      void MyClass::RunMyThread()

                                      my_thread = std::thread
                                      [this]
                                      while(m_timer.wait_for(std::chrono::seconds(2)))
                                      std::cout << "SendStatusInfo(some_info)n";

                                      ;


                                      // Destructor
                                      MyClass::~MyClass()
                                      std::cout << "~MyClass::MyClassn";
                                      m_timer.interrupt();
                                      my_thread.join();
                                      std::cout << "~MyClass::MyClass donen";


                                      int main()
                                      std::cout << "start of mainn";

                                      MyClass x;
                                      x.RunMyThread();
                                      using namespace std::literals;
                                      std::this_thread::sleep_for(11s);

                                      std::cout << "end of mainn";






                                      share|improve this answer
























                                        up vote
                                        0
                                        down vote










                                        up vote
                                        0
                                        down vote










                                        Additionally, I see that I need to use a std::mutex in conjunction with std::condition_variable? Is that really necessary? Is it not possible to achieve the goal by adding the std::condition_variable logic only to required places in the code piece here?




                                        std::condition_variable is a low level primitive. Actually using it requires fiddling with other low level primitives as well.



                                        struct timed_waiter 
                                        void interrupt()
                                        auto l = lock();
                                        interrupted = true;
                                        cv.notify_all();

                                        // returns false if interrupted
                                        template<class Rep, class Period>
                                        bool wait_for( std::chrono::duration<Rep, Period> how_long ) const
                                        auto l = lock();
                                        return !cv.wait_until( l,
                                        std::chrono::steady_clock::now() + how_long,
                                        [&]
                                        return !interrupted;

                                        );

                                        private:
                                        std::unique_lock<std::mutex> lock() const
                                        return std::unique_lock<std::mutex>(m);

                                        mutable std::mutex m;
                                        mutable std::condition_variable cv;
                                        bool interrupted = false;
                                        ;


                                        simply create a timed_waiter somewhere both the thread(s) that wants to wait, and the code that wants to interrupt, can see it.



                                        The waiting threads do



                                        while(m_timer.wait_for(std::chrono::minutes(2))) 
                                        SendStatusInfo(some_info);



                                        to interrupt do m_timer.interrupt() (say in the dtor) then my_thread.join() to let it finish.



                                        Live example:



                                        struct MyClass 
                                        ~MyClass();
                                        void RunMyThread();
                                        private:
                                        std::thread my_thread;
                                        timed_waiter m_timer;
                                        ;


                                        void MyClass::RunMyThread()

                                        my_thread = std::thread
                                        [this]
                                        while(m_timer.wait_for(std::chrono::seconds(2)))
                                        std::cout << "SendStatusInfo(some_info)n";

                                        ;


                                        // Destructor
                                        MyClass::~MyClass()
                                        std::cout << "~MyClass::MyClassn";
                                        m_timer.interrupt();
                                        my_thread.join();
                                        std::cout << "~MyClass::MyClass donen";


                                        int main()
                                        std::cout << "start of mainn";

                                        MyClass x;
                                        x.RunMyThread();
                                        using namespace std::literals;
                                        std::this_thread::sleep_for(11s);

                                        std::cout << "end of mainn";






                                        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 58 mins ago

























                                        answered 1 hour 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 35 mins ago

























                                                answered 43 mins ago









                                                Galik

                                                32k34673




                                                32k34673



























                                                     

                                                    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-an-stdthread-while-it-is-sleeping%23new-answer', 'question_page');

                                                    );

                                                    Post as a guest













































































                                                    Comments

                                                    Popular posts from this blog

                                                    White Anglo-Saxon Protestant

                                                    BuddyTV

                                                    Conflict (narrative)