I am using an std::thread
in my C++
code to constantly poll for some data & add it to a buffer. I use a C++ lambda
to start the thread like this:
StartMyThread() {
thread_running = true;
the_thread = std::thread { [this] {
while(thread_running) {
GetData();
}
}};
}
thread_running
is an atomic<bool>
declared in class header. Here is my GetData
function:
GetData() {
//Some heavy logic which needs to be executed in a worker thread
}
Next I also have a StopMyThread
function where I set thread_running
to false so that it exits out of the while loop in the lambda block
.
StopMyThread() {
thread_running = false;
the_thread.join();
}
It works well. The thread starts & stops without crashing.
This C++ code is used on iOS, Android, OS X and Windows. My application UI has a button which requires me to start & stop the thread on a button press; this button can be frequently used in some occasions. I can see a split second delay in UI while stopping or starting the thread.
My question is: In C++, is this a correct way to start/stop a thread frequently ? I think that with this logic I am creating a new thread every-time. And as I understand, creating a new thread makes the OS allocate lot of new resources which can be time-consoming. And I think this is the mistake I am doing. How can I avoid this ?
How can make use of the same thread without allocating new one repeatedly throughout the application lifecycle, and just play/pause it when required ?
a: Use punctuation (comma, ellipsis, dash) to indicate a pause or break. may be in the middle of a sentence or at the end of it. You can use commas, dashes, or ellipses to cue different types of pauses.
To pause a game in Unity, simply set the time scale to zero to pause it and back to one (the default) to unpause it again.
The pause menu is one of Minecraft's multiple menu screens. Activated during gameplay, it provides a portal to configure game options, quit out of a world, and more. This menu can be accessed anytime by pausing the game with the Esc key by default.
This is the classical example for the use of a condition variable. You wait on a mutex and notify a thread when a certain condition is fulfilled; this way you don't need to allocate a new thread when you need one, but this is not always a good thing, if you wish to save memory. An alternative would be a coroutine yielding to another coroutine when data is needed, which is arguably prettier. You need to implement coroutines yourself, or use a ready-made library, such as boost.coroutine
.
::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();
As it is often faster to free the lock before notifying, than vice-versa.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With