gpt4 book ai didi

c++ - 阻止取消 Boost.Asio 中挂起的异步操作

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:34:45 25 4
gpt4 key购买 nike

我有一个对象接收来自 boost::io_service 的回调,并且由于一些原因,我无法通过共享指针发布回调(是的,我知道这是处理它的官方方式),所以我将处理程序与原始指针绑定(bind)。假设在这种情况下它是固定要求。

现在,如果我删除该对象,它当然仍会收到关于未完成的套接字操作的回调,并带有“操作中止”错误代码。

问题:当我删除一个对象及其拥有的 Asio 对象(套接字、计时器)时,是否有办法强制同步完成所有操作?

最佳答案

你不能;那时信息已经丢失。您甚至无法比较函数对象的相等性,更不用说查看内部并比较一些指针然后决定要做什么了。

那么,问题是:为什么不能使用共享指针?

实现的方法是使用共享指针和弱指针。如果你不想使用共享指针和弱指针,你可以自己实现底层机制。但通常仅使用库实现更可靠。

因此,在回调中使用弱指针,让回调将 weak_ptr 作为参数,调用 wp.lock(),检查它,如果它仍然有效,则取消引用它。在您清除主 shared_ptr 和另一个调用 wp.lock() 的线程(假设您有多个线程)时,仍然会存在竞争条件,但您可以通过在对象中使用标志来解决此问题。

更新评论回复:

Asio 并不强制您使用 shared_ptr/weak_ptr 组合。您可以自由构建自己的解决方案,但您必须解决相同的问题。

假设您不能使用 weak_ptr,一旦确定没有其他对象会使用该指针,您应该删除该对象。原则上,您有两种基本方法可以做到这一点:

  1. 使用一些额外的数据结构检测对象已被删除。这是 shared_ptr/weak_ptr 内部所做的,您可以自由构建自己的等效项。

  2. 等待一切完成,然后删除该对象。不需要使用 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;
}

如果另一个线程正在调用 Obj::io_done(),那么调用 cancel_outstanding_operations() 会做什么?是等待它返回,还是因为I/O操作完成而立即返回?在“立即返回”的情况下,“delete o”语句是不安全的。在“等待它返回”的情况下,你有上面的“等待一切完成”的情况,除了你已经添加了一堆实现复杂性并且你必须同步等待。

关于c++ - 阻止取消 Boost.Asio 中挂起的异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6674211/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com