Skip to content

Instantly share code, notes, and snippets.

@ivankp
Created June 21, 2022 02:09
Show Gist options
  • Select an option

  • Save ivankp/f16dbff6039bec3284aaffefb7ccf2c4 to your computer and use it in GitHub Desktop.

Select an option

Save ivankp/f16dbff6039bec3284aaffefb7ccf2c4 to your computer and use it in GitHub Desktop.
#include <thread>
#include <mutex>
#include <condition_variable>
class worker_thread {
std::thread thread;
std::mutex mx;
std::condition_variable cv;
bool start = false, done = true, stop = false;
public:
template <typename F, typename... Args>
worker_thread(F&& f, Args&&... args)
: thread([this]<typename... Args2>(auto&& f, Args2&&... args){
for (;;) {
{ std::unique_lock lock(mx);
cv.wait(lock,[this]{ return start || stop; });
start = false;
if (stop) break;
}
f(static_cast<Args2&&>(args)...);
{ std::unique_lock lock(mx);
done = true;
}
cv.notify_all();
}
}, static_cast<F&&>(f), static_cast<Args&&>(args)...) { }
template <typename F, typename... Args>
void operator()(F&& f, Args&&... args) {
{ std::unique_lock lock(mx);
cv.wait(lock,[this]{ return done; });
f(static_cast<Args&&>(args)...);
start = true;
done = false;
}
cv.notify_all();
}
~worker_thread() {
{ std::unique_lock lock(mx);
cv.wait(lock,[this]{ return done; });
stop = true;
done = false;
}
cv.notify_all();
thread.join();
}
};
#include <iostream>
#include <chrono>
int main(int argc, char* argv[]) {
static int val;
worker_thread worker([]{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << val << std::endl;
});
for (int i=0; i++ < 1'000'000; ) {
if (i%200'000 == 0) {
worker([&]{ val = i; });
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment