13

最近玩了很多 Boost.Asio。我非常喜欢这个库,因为它提供了一种从当今多核系统中榨取性能的绝妙方法。

我曾经问过自己几次的一个问题,我认为在使用 Asio 进行异步调用时,关于对象生命周期/所有权的问题值得一提。

我反复遇到的问题是,您经常不得不“过期”一个仍然有异步回调待处理的对象。如果该对象在调用回调之前超出范围,则不可避免地会发生爆炸。

为了解决这个问题,我已将boost::enable_shared_from_this模板用作大多数基于 asio 的类的基类。这工作正常,但有点麻烦:通常这也意味着保护构造函数并向类添加工厂方法以确保在 shared_ptr 内创建所有实例。

我只是想知道其他人是如何解决这个问题的。我是最好的方法吗?还是我的 Asio.Foo 都错了?

讨论... :)

4

2 回答 2

2

使用boost::enable_shared_from_this几乎是做到这一点的方法。此外,boost::weak_ptr如果您需要对不应保留对象的对象的引用,如果它们是唯一保留的引用,请查看使用。

一个很好的使用示例weak_ptr:我enable_shared_from_this在我的套接字类中使用了boost::asio. boost::asio框架是唯一通过读写处理程序存储对对象的持久引用的东西。因此,当调用套接字的析构函数时,我知道套接字已关闭,我可以在处理程序中“做一些事情”以清理该关闭的套接字。使用套接字的应用程序只有一个对它的weak_ptr引用,shared_ptr当它想要使用套接字(通常是写入它)时,它会将其提升为一个。在套接字消失的情况下,可以检查该提升是否失败,尽管套接字的关闭处理程序通常会在此之前适当地清理所有weak_ptr引用。

于 2009-06-12T17:43:53.500 回答
1

这种事情不仅限于Asio。我最近写了一个线程池类(使用 Boost::Thread),它有几乎相同的问题——线程会调用创建它们的线程池类,以查看他们接下来必须执行的任务,使用普通指针如果线程池类在子线程仍在运行的情况下被销毁,程序就会崩溃。我通过调用线程池析构函数中的每个线程来处理它interrupt,然后在让析构函数返回之前等待所有线程退出。

如果我理解您的共享指针解决方案,它似乎在做同样的一般事情——确保在不再需要该项目之前不会被销毁。也是一个美观的解决方案。对于此类问题,我没有看到更好的答案。

于 2009-01-08T19:48:37.513 回答