Poco::ActiveDispatcher は、Poco::ActiveMethod と似ていますが、処理が厳密にシリアライズされるところが異なります。
つまり、処理指示がキューに積まれ、そのキューから引き出されたものが順番に処理されます。
処理順が保証されるので、例えばハードウエアのアクセスルーチンや通信などに使えるのではないかと思います。
デザインパターンで言うと、Single Threaded Execution パターンになります。
ここでは、前回と同じく、別スレッドでの処理に単純な整数の掛け算をやっています。
ActiveDispatcherTest.cpp
#include <Poco/ActiveMethod.h> #include <Poco/ActiveDispatcher.h> #include <Poco/ActiveResult.h> #include <Poco/Format.h> #include <Poco/Random.h> #include <deque> #include "ScopedLogMessage.h" #include "PrepareConsoleLogger.h" struct MultiplierData { int threadID; int callCount; std::pair<int, int> source; int result; MultiplierData() { threadID = 0; callCount = 0; source.first = 0; source.second = 0; result = 0; } }; class ActiveMultiplierDispatcher : public Poco::ActiveDispatcher { public: ActiveMultiplierDispatcher() : multiply(this, &ActiveMultiplierDispatcher::multiplyImpl) , m_callCount(0) , m_msg(" ActiveMultiplierDispatcher ", "start", "end") { } Poco::ActiveMethod<MultiplierData, MultiplierData, ActiveMultiplierDispatcher, Poco::ActiveStarter<Poco::ActiveDispatcher> > multiply; protected: // Single Threaded Execution pattern MultiplierData multiplyImpl(const MultiplierData& args) { ScopedLogMessage msg(" ActiveMultiplierDispatcher::multiplyImpl ", "start", "end"); ++m_callCount; msg.Message( Poco::format(" ActiveMultiplierDispatcher::multiply(%d*%d) invoked from thread[%d] [callCount=%d]" , args.source.first , args.source.second , args.threadID , m_callCount) ); // simulate time consuming job Poco::Thread::sleep(500); // 500mSec MultiplierData rtn = args; rtn.callCount = m_callCount; rtn.result = args.source.first * args.source.second; return rtn; } int m_callCount; ScopedLogMessage m_msg; }; MultiplierData PrepareMultiplierData(Poco::Random& random) { MultiplierData data; Poco::Thread* p_thread = Poco::Thread::current(); data.threadID = (0 == p_thread) ? 0:p_thread->id(); data.source.first = std::abs(random.nextChar() % 10); data.source.second = std::abs(random.nextChar() % 10); return data; } int main(int /*argc*/, char** /*argv*/) { PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION); ScopedLogMessage msg("ActiveDispatcherTest ", "start", "end"); Poco::Random random; std::deque< Poco::ActiveResult<MultiplierData> > activeResults; ActiveMultiplierDispatcher multiplier; const int kNumMutiplier = 2; for(int i=0; i<kNumMutiplier; ++i) { // Future pattern activeResults.push_back(multiplier.multiply(PrepareMultiplierData(random))); } // some other task can be done here msg.Message(" doing something..."); while(0 != activeResults.size()) { Poco::ActiveResult<MultiplierData>& result = activeResults.front(); result.wait(); msg.Message( Poco::format(" ActiveMultiplierDispatcher::multiply(%d*%d) result=%d [callCount=%d]" , result.data().source.first , result.data().source.second , result.data().result , result.data().callCount) ); activeResults.pop_front(); } return 0; } |
Results of execution
・ActiveMultiplierDispatcher のインスタンスに掛け算を2回指示。
・別のスレッドで指示順に掛け算実行。
・その隙に、メインスレッドで何か実行。
・メインスレッドで計算結果表示。
[0] ActiveDispatcherTest start [0] ActiveMultiplierDispatcher start [0] doing something... [1] ActiveMultiplierDispatcher::multiplyImpl start [1] ActiveMultiplierDispatcher::multiply(7*7) invoked from thread[0] [callCount=1] [1] ActiveMultiplierDispatcher::multiplyImpl end [1] ActiveMultiplierDispatcher::multiplyImpl start [0] ActiveMultiplierDispatcher::multiply(7*7) result=49 [callCount=1] [1] ActiveMultiplierDispatcher::multiply(4*6) invoked from thread[0] [callCount=2] [1] ActiveMultiplierDispatcher::multiplyImpl end [0] ActiveMultiplierDispatcher::multiply(4*6) result=24 [callCount=2] [0] ActiveMultiplierDispatcher end [0] ActiveDispatcherTest end |
Downloads
・ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年4月23日からのダウンロード数:1238
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
![]() |
Copyright © 2010 Round Square Inc. All rights reserved. |
---|
0 Comments.