Poco::ActiveMethod は、Future Pattern を実現するためのものです。
要点を言えば、ある処理を別スレッドで起動し、起動元スレッドでは、その処理が終了するまで
(何か別のことでもしながら)待って、その処理結果を使うという感じです。
# ちなみに私は Future Pattern を「下請けに丸投げー納入チェックのみ」パターンと呼んでいます。
別スレッドでの処理に適当なものが思いつかなかったので、単純な整数の掛け算をやってみました。
ActiveMethodTest.cpp
#include <Poco/ActiveMethod.h> #include <Poco/ActiveResult.h> #include <Poco/Format.h> #include <Poco/Random.h> #include <deque> #include "ScopedLogMessage.h" #include "PrepareConsoleLogger.h" class ActiveMultiplier; struct MultiplierData { int threadID; ActiveMultiplier* multiplier; int callCount; std::pair<int, int> source; int result; MultiplierData() { threadID = 0; multiplier = NULL; callCount = 0; source.first = 0; source.second = 0; result = 0; } }; class ActiveMultiplier { public: ActiveMultiplier() : multiply(this, &ActiveMultiplier::multiplyImpl) , m_callCount(0) , m_msg(" ActiveMultiplier ", "start", "end") { } Poco::ActiveMethod<MultiplierData, MultiplierData, ActiveMultiplier> multiply; private: MultiplierData multiplyImpl(const MultiplierData& args) { ScopedLogMessage msg(" ActiveMultiplier::multiplyImpl ", "start", "end"); ++m_callCount; msg.Message( Poco::format(" ActiveMultiplier::multiply(%d*%d) invoked from thread[%d] [callCount=%d]" , args.source.first , args.source.second , args.threadID , m_callCount) ); 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(ActiveMultiplier* multiplier, Poco::Random& random) { MultiplierData data; Poco::Thread* p_thread = Poco::Thread::current(); data.threadID = (0 == p_thread) ? 0:p_thread->id(); data.multiplier = multiplier; 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("ActiveMethodTest ", "start", "end"); Poco::Random random; std::deque< Poco::ActiveResult<MultiplierData> > activeResults; const int kNumMutiplier = 2; for(int i=0; i<kNumMutiplier; ++i) { ActiveMultiplier* multiplier = new ActiveMultiplier; // Future pattern activeResults.push_back(multiplier->multiply(PrepareMultiplierData(multiplier, 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(" ActiveMultiplier::multiply(%d*%d) result=%d [callCount=%d]" , result.data().source.first , result.data().source.second , result.data().result , result.data().callCount) ); delete result.data().multiplier; activeResults.pop_front(); } return 0; } |
Results of execution
・ActiveMultiplier のインスタンス毎に別のスレッドで掛け算。
・その隙に、メインスレッドで何か実行。
・メインスレッドで計算結果表示。
[0] ActiveMethodTest start [0] ActiveMultiplier start [0] ActiveMultiplier start [1] ActiveMultiplier::multiplyImpl start [0] doing something... [2] ActiveMultiplier::multiplyImpl start [1] ActiveMultiplier::multiply(9*4) invoked from thread[0] [callCount=1] [1] ActiveMultiplier::multiplyImpl end [0] ActiveMultiplier::multiply(9*4) result=36 [callCount=1] [2] ActiveMultiplier::multiply(6*3) invoked from thread[0] [callCount=1] [0] ActiveMultiplier end [2] ActiveMultiplier::multiplyImpl end [0] ActiveMultiplier::multiply(6*3) result=18 [callCount=1] [0] ActiveMultiplier end [0] ActiveMethodTest end |
Downloads
・ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年4月21日からのダウンロード数:1164
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
![]() |
Copyright © 2010 Round Square Inc. All rights reserved. |
---|
0 Comments.