CRTPでPollingスレッド
polling_base.hpp
#ifndef HWM_POLLING_BASE_HPP #define HWM_POLLING_BASE_HPP //! @file //! do processing every specifiec time. #include <boost/bind.hpp> #include <boost/thread.hpp> template< typename Derived, typename TimeDuration = boost::posix_time::time_duration > class polling_base { protected: //! ctor polling_base( TimeDuration const &waiting_time = boost::posix_time::milliseconds(1000), bool const initial_suspended = false) : wait_ (waiting_time) , terminated_ (true) , suspended_ (initial_suspended) { initialize(); } ~polling_base() { terminate(); } public: TimeDuration const & get_wait_time () const { return wait_; } //! set waiting time. //! T must be assignable to TimeDuration template<typename T> void set_wait_time (T const &wait) { wait_ = wait; } bool is_suspended () const { return suspended_; } void suspend () { if(!is_suspended()) { boost::lock_guard<boost::mutex> lock(lock_); suspended_ = true; } } void resume () { { boost::lock_guard<boost::mutex> lock(lock_); suspended_ = false; } cond_.notify_one(); } private: void initialize () { if(is_terminated()) { terminated_ = false; thread_ = boost::thread(boost::bind(&polling_base::polling, this)); } } void terminate () { terminated_ = true; thread_.join(); } bool is_terminated () const { return terminated_; } //! polling here private: void polling () { while(!is_terminated()) { boost::this_thread::sleep(wait_); boost::unique_lock<boost::mutex> lock(lock_); while(is_suspended()) { cond_.wait(lock); if(is_terminated()) { goto BREAK_POLLING; } } //! Derived class processes. static_cast<Derived &>(*this).polling_process(); } BREAK_POLLING: (void *)0; } private: boost::thread thread_; boost::condition_variable cond_; boost::mutex lock_; TimeDuration wait_; bool terminated_; bool suspended_; }; #endif //HWM_POLLING_BASE_HPP
test.cpp
#include <iostream> #include "./polling.hpp" class A : public polling_base<A> { typedef polling_base<A> base_type; public: A() : base_type(boost::posix_time::milliseconds(1000)) {} //! これだけ定義 void polling_process() { std::cout << "Hello world." << std::endl; } }; int main() { A a; int dummy = 0; std::cin >> dummy; a.suspend(); a.suspend(); //複数回呼んでも問題ない std::cout << "suspended" << std::endl; std::cin >> dummy; a.resume(); a.resume(); std::cout << "resumed" << std::endl; a.set_wait_time(a.get_wait_time() / 10); a.set_wait_time(a.get_wait_time() * 2); std::cin >> dummy; }