I'm writing a program whose main thread spawns a worker thread that performs some work, sleeps for a set amount of time in an infinite loop, i.e. the worker thread executes:
void do_work() {
for (;;) {
// do some work
std::this_thread::sleep_for(100ms);
}
}
Now, I would additionally like to be able to temporarily completely disable this worker thread from the main thread, i.e. I would like to write the following functions:
disable_worker():
disable the worker threadenable_worker()
: enable the worker thread again
What I've come up with is the following:
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>
using namespace std::literals::chrono_literals;
bool enabled;
std::mutex mtx;
std::condition_variable cond;
void disable_worker() {
std::lock_guard<std::mutex> lock(mtx);
enabled = false;
}
void enable_worker() {
{
std::lock_guard<std::mutex> lock(mtx);
enabled = true;
}
cond.notify_one();
}
void do_work() {
for (;;) {
std::unique_lock<std::mutex> lock(mtx);
cond.wait(lock, []{ return enabled; });
// ... do some work ...
std::this_thread::sleep_for(100ms);
}
}
int main() {
std::thread t(do_work);
// ... enable/disable t as necessary ...
}
I suppose this works (at least I can't spot any issues), however, I would also like to guarantee that when either of enable_worker
and disable_worker
return (in the main thread), the working thread is guaranteed to be either blocking on the condition variable or sleeping, i.e. not performing any work. How can I implement this without any race conditions?
Aucun commentaire:
Enregistrer un commentaire