{提升 1.54}
所有 asio 操作都发生在同一个 io_service 上,它的 run() 从几个 std::threads 调用(因此是一个线程池)
struct Async : std::enable_shared_from_this<Async>
{
boost::signals2::signal<void()> m_sig;
void read()
{
auto self = shared_from_this();
boost::asio::async_read_until(
/*socket*/,
/*bufferToCollectData*/,
/*delimiter*/,
[self]{self->onRead(..);}
);
}
void onRead(..)
{
m_sig();
}
};
struct Process : std::enable_shared_from_this<Process>
{
std::shared_ptr<Async> m_shrPtrAsync;
boost::signals2::connection m_connection;
void start()
{
m_shrPtrAsync = std::make_shared<Async>();
//m_shrPtrAsync->startUpThings();
auto self = shared_from_this();
m_connection = m_shrPtrAsync->m_sig.connect(
[self]{self->slot();}
);
}
void stop()
{
//this will not delete the slot and have to wait indefinitely until some operation happens on m_sig.
//------------------------------- <2>
m_connection.disconnect();
//this should force the original slot deletion.
m_connection = m_shrPtrAsync->m_sig.connect([this]{dummy();});
m_connection.disconnect();
}
void dummy() {}
void slot()
{
auto self = shared_from_this(); //-------------------- <1>
//to not block the calling thread (Async's m_sig())
m_strand.post(
[self]{self->slotPrivateImpl();}
);
}
void slotPrivateImpl() { /*Processing*/ }
};
//This is from the main thread outside the thread-pool
{//local scope begins
auto shrPtrProcess = std::make_shared<Process>();
shrPtrProcess->start();
//after sometime
shrPtrProcess->stop();
}//local scope ends. I want shrPtrProcess to delete the contained pointer here
//which should in turn delete the Async's pointer in shrPtrProcess->m_shrPtrAsync
这安全吗?当主线程执行shrPtrProcess->stop();
从而从异步中删除插槽m_sig
然后从本地范围中出来时,对 shared_ptr 的最后一个剩余引用Process
将死亡从而破坏它,但其他线程触发m_sig
可能已经进入Process::slot(
) 到那时并即将执行行上面标有<1>。信号2是否保证插槽在完全执行之前不会被删除?
如果这不安全,那么我如何实现这种shrPtrProcess
破坏ptr 的行为,一旦本地范围结束Process
,又会破坏Async
原始 ptr ?shrPtrAsync
如果我没有在上面标记为 <2> 的地方进行 hack,如果 m_sig() 不再触发,因为signals2::connection::disconnect()
不会导致立即删除插槽,我将永远无法释放资源。