Poco::Util::TimerTask オブジェクトをバックグランドで実行するためにスケジューリングする Poco::Util::Timer を紹介します。
Poco::Util::Timer は、スケジューリングされたタスクを1つのスレッドで順番に処理するので、それぞれのタスクの処理は速やかに終わるようにしないと、それに続くタスクの処理が遅れてしまいます。
スケジューリングには次の3つの方法があります:
Method | Description |
---|---|
schedule(TimerTask::Ptr pTask, Poco::Timestamp time) | 時刻指定の単発 |
schedule(TimerTask::Ptr pTask, long delay, long interval) schedule(TimerTask::Ptr pTask, lPoco::Timestamp time, long interval) |
初回ディレイ指定または時刻指定で繰り返し 繰り返しは、タスクの終了時基準 |
scheduleAtFixedRate(TimerTask::Ptr pTask, long delay, long interval) scheduleAtFixedRate(TimerTask::Ptr pTask, lPoco::Timestamp time, long interval) |
初回ディレイ指定または時刻指定で繰り返し 繰り返しは、タスクの開始時基準 |
スレッドセーフになっているので、複数のスレッドから Poco::Util::Timer にタスクをスケジューリングしても大丈夫です。
UtilTimerTest.cpp
・MyTimerTask::onTimer 内に 100msec のディレイを入れ、イベントを投げる。
・TestSchedule() では、500msec 後に MyTimerTask::onTimer が一度だけ呼ばれるように
スケジューリングし、イベント待ち。
・TestFixedRate() では、500msec 後から MyTimerTask::onTimer が 500msec 毎に呼ばれるように
scheduleAtFixedRate でスケジューリングし、イベント待ち。
・TestFixedRate() では、500msec 後から MyTimerTask::onTimer が 500msec 毎に呼ばれるように
schedule でスケジューリングし、イベント待ち。
#include <Poco/Util/Timer.h> #include <Poco/Util/TimerTask.h> #include <Poco/Util/TimerTaskAdapter.h> #include <Poco/Event.h> #include <Poco/Timestamp.h> #include <Poco/Format.h> #include <string> #include "ScopedLogMessage.h" #include "PrepareConsoleLogger.h" class MyTimerTask { public: MyTimerTask(ScopedLogMessage& msg, Poco::Event& event) : m_msg(msg) , m_event(event) { } void onTimer(Poco::Util::TimerTask& task) { m_msg.Message(" MyTimerTask::onTimer() called"); Poco::Thread::sleep(100); // 100msec m_event.set(); } private: ScopedLogMessage& m_msg; Poco::Event& m_event; }; void TestSchedule(ScopedLogMessage& msg, Poco::Util::Timer& timer) { msg.Message("--- schedule ---"); const Poco::Timestamp::TimeDiff kTimeDiff = 500000; // 500msec Poco::Event event; MyTimerTask task(msg, event); Poco::Util::TimerTask::Ptr pTask = new Poco::Util::TimerTaskAdapter<MyTimerTask>(task, &MyTimerTask::onTimer); Poco::Timestamp time; time += kTimeDiff; timer.schedule(pTask, time); event.wait(); msg.Message(Poco::format(" execution delay from scheduled: %Ldusec" , pTask->lastExecution().epochMicroseconds()-time.epochMicroseconds())); } Poco::Timestamp::TimeVal WaitAndShowTime( ScopedLogMessage& msg , Poco::Event& event , Poco::Util::TimerTask::Ptr& pTask , const std::string& text , Poco::Timestamp::TimeVal refTime) { event.wait(); Poco::Timestamp::TimeVal val = pTask->lastExecution().epochMicroseconds(); msg.Message(Poco::format("%s %7.3fmsec", text, 0.001*(val-refTime))); return val; } void TestFixedRate(ScopedLogMessage& msg, Poco::Util::Timer& timer) { msg.Message("--- schedule fixed rate ---"); Poco::Event event; MyTimerTask task(msg, event); Poco::Util::TimerTask::Ptr pTask = new Poco::Util::TimerTaskAdapter<MyTimerTask>(task, &MyTimerTask::onTimer); Poco::Timestamp time; timer.scheduleAtFixedRate(pTask, 500, 500); // 500msec Poco::Timestamp::TimeVal val; val = WaitAndShowTime(msg, event, pTask, " delay :", time.epochMicroseconds()); for(int i=0; i<2; ++i) { val = WaitAndShowTime(msg, event, pTask, " interval:", val); } pTask->cancel(); } void TestInterval(ScopedLogMessage& msg, Poco::Util::Timer& timer) { msg.Message("--- schedule interval ---"); Poco::Event event; MyTimerTask task(msg, event); Poco::Util::TimerTask::Ptr pTask = new Poco::Util::TimerTaskAdapter<MyTimerTask>(task, &MyTimerTask::onTimer); Poco::Timestamp time; timer.schedule(pTask, 500, 500); // 500msec Poco::Timestamp::TimeVal val; val = WaitAndShowTime(msg, event, pTask, " delay :", time.epochMicroseconds()); for(int i=0; i<2; ++i) { val = WaitAndShowTime(msg, event, pTask, " interval:", val); } pTask->cancel(); } int main(int /*argc*/, char** /*argv*/) { PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION); ScopedLogMessage msg("UtilTimerTest ", "start", "end"); Poco::Util::Timer timer; TestSchedule(msg, timer); TestFixedRate(msg, timer); TestInterval(msg, timer); return 0; } |
Results of execution
・TestFixedRate() では、interval が 500msec
・TestInterval() では、interval が 600msec (500msec + 100msec)
・MyTimerTask 側は thread ID が 1
[0] UtilTimerTest start [0] --- schedule --- [1] MyTimerTask::onTimer() called [0] execution delay from scheduled: 259usec [0] --- schedule fixed rate --- [1] MyTimerTask::onTimer() called [0] delay : 500.117msec [1] MyTimerTask::onTimer() called [0] interval: 500.236msec [1] MyTimerTask::onTimer() called [0] interval: 500.253msec [0] --- schedule interval --- [1] MyTimerTask::onTimer() called [0] delay : 500.170msec [1] MyTimerTask::onTimer() called [0] interval: 600.252msec [1] MyTimerTask::onTimer() called [0] interval: 600.240msec [0] UtilTimerTest end |
Downloads
・ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年5月29日からのダウンロード数:1128
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
![]() |
Copyright © 2010 Round Square Inc. All rights reserved. |
---|
0 Comments.