c++ - Resetting sleeping time of a thread -
suppose have thread
void mythread() { int res; while(1) { { boost::lock_guard<boost::mutex> lock(mylock); res = do_my_stuff(); } boost::this_thread::sleep(boost::posix_time::seconds(5)); } }
and thread sleeping. if happens outside of thread, i'd able increase sleep time.
what best way it?
using condition_variable
signal changes deadline
this has benefit of supporting scenarios timeout shortened:
see live on coliru
#include <thread> #include <chrono> #include <iostream> #include <condition_variable> namespace demo { namespace chrono = std::chrono; using our_clock = chrono::system_clock; struct worker { mutable std::mutex _mx; // shared, protected _mx: our_clock::time_point _deadline; mutable std::condition_variable _cv; worker(our_clock::time_point deadline) : _deadline(deadline) {} void operator()() const { std::unique_lock<std::mutex> lk(_mx); _cv.wait_until(lk, _deadline, [this] { std::cout << "worker: signaled\n"; auto = our_clock::now(); if (now >= _deadline) return true; std::cout << "worker: still waiting " << chrono::duration_cast<chrono::milliseconds>(_deadline - now).count() << "ms...\n"; return false; }); std::cout << "worker: done\n"; } }; } int main() { using namespace demo; worker worker(our_clock::now() + chrono::seconds(2)); auto th = std::thread(std::cref(worker)); // after 2 seconds, update timepoint std::this_thread::sleep_for(chrono::seconds(1)); { std::lock_guard<std::mutex> lk(worker._mx); std::cout << "updating shared delay value..." << "\n"; worker._deadline = our_clock::now() + chrono::seconds(1); worker._cv.notify_all(); } th.join(); }
c++11 standard library (no signaling)
here's standard-library approach uses no synchronization around deadline.
i'd have preferred use atomic time_point
deadline value itself, that's not supported. next best thing have been shared_ptr<time_point>
(with std::atomic_load
/atomic_store
) compiler's library doesn't implement yet (grrr).
so, instead, share 'offset' since start time:
#include <thread> #include <chrono> #include <iostream> #include <atomic> namespace demo { namespace chrono = std::chrono; using our_clock = chrono::system_clock; using shared_delay = std::atomic<our_clock::duration>; void worker(our_clock::time_point const start, shared_delay const& delay) { (our_clock::time_point deadline; our_clock::now() < (deadline = start + delay.load());) { std::cout << "worker: sleeping " << chrono::duration_cast<chrono::milliseconds>(deadline - our_clock::now()).count() << "ms...\n"; std::this_thread::sleep_until(deadline); } std::cout << "worker: done\n"; } } int main() { using namespace demo; shared_delay delay(chrono::seconds(2)); auto th = std::thread(worker, our_clock::now(), std::cref(delay)); // after 2 seconds, update timepoint std::this_thread::sleep_for(chrono::seconds(1)); std::cout << "updating shared delay value..." << "\n"; delay.store(chrono::seconds(3)); th.join(); }
see live on coliru
Comments
Post a Comment