在许多情况下,我的类就像活动对象(有一个线程)。并且为了避免访问冲突,我总是必须等待加入析构函数。这通常不是问题。
然而,想象一个带有一些错误(死锁、活锁等)的发布版本会导致join()
无法按时返回或根本无法返回,这将导致整个应用程序在等待不再使用的对象时变得无法正常工作。如果这种情况发生在客户身上,它就会成为一个问题。
我宁愿收到问题通知并跳过加入。并泄漏线程及其资源。
跳过连接可以通过这样的方式来实现。
class MyActiveObject
{
public:
MyActiveObject();
~MyActiveObject(){}
private
struct Implementation;
std::shared_ptr<Implementation> pImpl_;
};
struct MyActiveObject::Implementation : std::enable_shared_from_this<Implementation >
{
Implementation() : thread_([=]{Run();})
{
}
~Implementation()
{
#ifdef _DEBUG
thread_.join();
#else
if(!thread_.timed_join(SOME_TIMEOUT))
ALERT_SOME_HOW();
#endif
}
void Dispose()
{
isRunning_ = false;
}
void Run()
{
#ifndef _DEBUG
auto pKeepAlive = shared_from_this(); // Won't be destroyed until thread finishes
#endif
isRunning_ = true;
while(isRunning_)
{
/* ... */
}
}
boost::thread thread_;
tbb::atomic<bool> isRunning_;
};
MyActiveObject::MyActiveObject() : pImpl_(new Implementation()){}
MyActiveObject::~MyActiveObject() { pImpl_->Dispose(); }
这是一个好主意吗?还是有更好的策略?