同期イベント処理のための複数の戦略へのインターフェースとして機能するBaseクラスがあります。ここで、イベントを非同期的に処理する戦略が必要です。コードのリファクタリングを最小限に抑えるために、各戦略には非同期イベント処理用の独自の内部スレッドがあります。私の主な関心事は、このスレッドのライフサイクルをどのように管理するかです。派生ストラテジークラスは、コードベース全体で構築および破棄されるため、ストラテジークラスの外部でスレッドのライフサイクル(開始/停止)を管理することは困難です。
私は次のコードになりました:
#include <iostream>
#include <cassert>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
struct Base
{
virtual ~Base()
{
std::cout << "In ~Base()" << std::endl;
// For testing purpose: spend some time in Base dtor
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}
virtual void processEvents() = 0;
void startThread()
{
if(_thread)
{
stopThread();
}
_thread.reset(new boost::thread(&Base::processEvents, this));
assert(_thread);
}
void stopThread()
{
if(_thread)
{
std::cout << "Interrupting and joining thread" << std::endl;
_thread->interrupt();
_thread->join();
_thread.reset();
}
}
boost::shared_ptr<boost::thread> _thread;
};
struct Derived : public Base
{
Derived()
{
startThread();
}
virtual ~Derived()
{
std::cout << "In ~Derived()" << std::endl;
// For testing purpose: make sure the virtual method is called while in dtor
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
stopThread();
}
virtual void processEvents()
{
try
{
// Process events in Derived specific way
while(true)
{
// Emulated interruption point for testing purpose
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
std::cout << "Processing events..." << std::endl;
}
}
catch (boost::thread_interrupted& e)
{
std::cout << "Thread interrupted" << std::endl;
}
}
};
int main(int argc, char** argv)
{
Base* b = new Derived;
delete b;
return 0;
}
ご覧のとおり、スレッドは中断され、Derivedクラスのデストラクタに参加しています。Stackoverflowに関する多くのコメントは、デストラクタのスレッドに参加することは悪い考えであると主張しています。ただし、Derivedクラスの構築/破棄を通じてスレッドのライフサイクルを管理する必要があるという制約を考慮すると、これ以上のアイデアは見つかりません。誰かがより良い提案をしていますか?