我有一个从boost::io_service
接收回调,并且由于一些原因我不能发布通过共享指针回调(是的,我知道这是到正式方法的对象处理它),所以我用一个原始指针绑定处理程序。假设在这种情况下它是一个固定的要求。的阻塞取消Boost.Asio的
现在,如果我删除的对象,它将,当然,仍然收到一个回调在一个优秀的套接字操作与“操作中止”错误代码。
的问题:有没有办法强制所有操作的同步完成时,我与它拥有短耳对象(插座,定时器)一起删除的对象?
我有一个从boost::io_service
接收回调,并且由于一些原因我不能发布通过共享指针回调(是的,我知道这是到正式方法的对象处理它),所以我用一个原始指针绑定处理程序。假设在这种情况下它是一个固定的要求。的阻塞取消Boost.Asio的
现在,如果我删除的对象,它将,当然,仍然收到一个回调在一个优秀的套接字操作与“操作中止”错误代码。
的问题:有没有办法强制所有操作的同步完成时,我与它拥有短耳对象(插座,定时器)一起删除的对象?
你不能;那时信息已经丢失了。你甚至无法比较函数对象是否相等,更不用说偷看内部并比较一些指针,然后决定做什么。
所以,问题是:为什么你不能使用共享指针?
做到这一点的方法是使用共享指针和弱指针。如果你不想使用共享指针和弱指针,你可以自己实现底层机制。但是使用库实现通常更可靠。
因此,在回调中使用弱指针,让回调以weak_ptr作为参数,调用wp.lock(),检查它,如果它仍然有效,则对其进行解引用。在清除主shared_ptr和调用wp.lock()的另一个线程(假设您有多个线程)的情况下,仍然会出现争用情况,但您可以通过在对象中使用标记来解决此问题。
更新与响应发表评论:
短耳并没有强迫你使用一个shared_ptr/weak_ptr的组合。您可以自由构建自己的解决方案,但必须解决相同的问题。
假设你不能使用weak_ptr,你应该删除对象,一旦你确定没有别的东西会使用指针。原则上你有两种基本的方法:
通过使用一些额外的数据结构来检测该对象已被删除。这是shared_ptr/weak_ptr在内部执行的操作,您可以自由构建自己的等效项。
等待一切完成,然后删除该对象。不需要使用shared_ptr/weak_ptr,但您需要以某种方式执行本书。
在这些情况下,您最终会通过手动或使用库来跟踪哪些优秀。基本的任务是一样的,但你并不是被迫使用一个库。你被迫解决这个普遍问题。
你所要求的,同步“取消”每个优秀的操作,让您可以安全地删除对象的方式,减少对这些案件之一。
考虑:
class Obj {
void queue() { wait_for_io(this, bind(&Obj::io_done, this, _1)); }
void io_done(error_code const& error)
{
// Do stuff.
}
};
void kill_object(Obj* o)
{
cancel_outstanding_operations_for_obj(o);
delete o;
}
什么调用cancel_outstanding_operations()做,如果调用的OBJ :: io_done()过程中的另一个线程?它是否等待它返回,还是因为I/O操作完成而立即返回?在“立即返回”的情况下,“delete o”语句并不安全。在“等待它返回”的情况下,除了已经添加了一堆实现复杂性并且必须同步执行等待外,您还有上面的“等待所有事情完成”的情况。
是的我明白我可以使用weak_ptr,但假设我不能。似乎很愚蠢的是,没有安全的方法来取消未使用shared_ptr的挂起操作。事实上,似乎Asio *强制我使用共享/弱指针进行异步回调,而不会留下任何摆动空间。更糟的是,这迫使我对一个对象有一种“limbo”状态,当它从应用程序逻辑的角度来看不再有效时,但仍然可以接收到一个Asio回调。 –