The right way to pause and resume std :: thread

I use std::thread in my C++ code to constantly poll some data and add it to the buffer. I use C++ lambda to start the stream as follows:

 StartMyThread() { thread_running = true; the_thread = std::thread { [this] { while(thread_running) { GetData(); } }}; } 

thread_running is an atomic<bool> declared in the class header. Here is my GetData function:

 GetData() { //Some heavy logic which needs to be executed in a worker thread } 

Further, I also have a StopMyThread function, where I set thread_running to false so that it thread_running while loop in the lambda block .

 StopMyThread() { thread_running = false; the_thread.join(); } 

It works well. The thread starts and stops without fail.

This C ++ code is used on iOS, Android, OS X, and Windows. There is a button in my user interface that requires me to start and stop the flow with the click of a button; This button can often be used in some cases. I see a delay per second in the user interface when a thread stops or starts.

My question is: In C ++, is this the correct way to start / stop a thread often? I think that with this logic, I create a new thread every time. And, as I understand it, creating a new thread forces the OS to allocate a lot of new resources, which may be temporary. And I think this is the mistake I am making. How can i avoid this?

How to use the same stream without highlighting it once throughout the entire life cycle of the application, and just play / pause it if necessary?

+3
source share
1 answer

This is a classic example of using a condition variable. You wait for the mutex and notify the thread when a certain condition is met; this way you don’t need to allocate a new thread when you need it, but it is not always good if you want to save memory. An alternative would be a coroutine that brings another coroutine when data is needed, which is perhaps more beautiful. You need to implement coroutines yourself or use ready-made libraries, for example boost.coroutine .

Example

 ::std::condition_variable cv_; ::std::mutex m_; bool data_is_ready_{}; StartMyThread() { ::std::thread([this] { for (;;) { ::std::unique_lock<decltype(m_)> l(m_); cv.wait(l, [this]{ return data_is_ready_; }); // do your stuff, m_ is locked data_is_ready_ = false; } } ).detach(); } 

To notify:

 { ::std::unique_lock<decltype(m_)> l(m_); data_is_ready_ = true; } cv_.notify_one(); 

How often is it faster to release a lock before notification than vice versa.

+3
source

Source: https://habr.com/ru/post/1259602/


All Articles