如何设计boost :: asio套接字或其包装的正确释放 [英] How to design proper release of a boost::asio socket or wrapper thereof

查看:98
本文介绍了如何设计boost :: asio套接字或其包装的正确释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试了几年没有接触过boost :: asio的简单的异步TCP服务器.

I am making a few attempts at making my own simple asynch TCP server using boost::asio after not having touched it for several years.

我可以找到的最新示例清单是: http://www.boost. org/doc/libs/1_54_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html

The latest example listing I can find is: http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html

此示例清单中的问题是(我觉得)通过将tcp_connection设置为shared_ptr可以欺骗并欺骗很大,这样就不必担心每个连接的生命周期管理. (我认为)为简洁起见,他们这样做是因为它只是一个小教程,但是该解决方案不是真实世界.

The problem I have with this example listing is that (I feel) it cheats and it cheats big, by making the tcp_connection a shared_ptr, such that it doesn't worry about the lifetime management of each connection. (I think) They do this for brevity, since it is a small tutorial, but that solution is not real world.

如果您希望在计时器或类似的计时器上向每个客户端发送消息怎么办?在任何实际的非平凡服务器中,都必须有客户端连接的集合.

What if you wanted to send a message to each client on a timer, or something similar? A collection of client connections is going to be necessary in any real world non-trivial server.

我担心每个连接的生命周期管理.我认为自然而然的事情是将tcp_connection对象或指向它们的指针的一些集合保留在tcp_server中.从OnConnect回调添加到该集合,然后从该集合中删除OnDisconnect.

I am worried about the lifetime management of each connection. I figure the natural thing to do would be to keep some collection of tcp_connection objects or pointers to them inside tcp_server. Adding to that collection from the OnConnect callback and removing from that collection OnDisconnect.

请注意,在发生错误的情况下,很有可能会从实际的Disconnect方法调用OnDisconnect,而该方法又会从OnReceive回调或OnSend回调调用.

Note that OnDisconnect would most likely be called from an actual Disconnect method, which in turn would be called from OnReceive callback or OnSend callback, in the case of an error.

好,问题就出在这里.

考虑一下,我们会有一个看起来像这样的调用栈:

Consider we'd have a callstack that looked something like this:

tcp_connection::~tcp_connection
tcp_server::OnDisconnect
tcp_connection::OnDisconnect
tcp_connection::Disconnect
tcp_connection::OnReceive

这将导致错误,因为调用栈解散,并且我们正在将对象的析构函数称为...的对象中执行代码.

This would cause errors as the call stack unwinds and we are executing code in a object that has had its destructor called...I think, right?

我想每个进行服务器编程的人都会以某种方式遇到这种情况.处理它的策略是什么?

I imagine everyone doing server programming comes across this scenario in some fashion. What is a strategy for handling it?

我希望所作的解释足以引起人们的注意.如果不能让我知道,我将创建自己的源代码清单,但是它将很大.

I hope the explanation is good enough to follow. If not let me know and I will create my own source listing, but it will be very large.

相关

)异步C ++代码中的内存管理

IMO不是一个可接受的答案,它依赖于在接收呼叫时表现出色的shared_ptr作弊,仅此而已,并且不是真实世界.如果服务器要每5分钟对所有客户端说嗨"怎么办.某种类型的集合是必需的.如果您在多个线程上调用io_service.run怎么办?

IMO not an acceptable answer, relies on cheating with shared_ptr outstanding on receive calls and nothing more, and is not real world. what if the server wanted to say "Hi" to all clients every 5 minutes. A collection of some kind is necessary. What if you are calling io_service.run on multiple threads?

我还询问了增强邮件列表: http://boost.2283326.n4.nabble.com/How-to-design-proper-release-of-a-boost-asio-socket-or-wrapper-thereof-td4693442.html

I am also asking on the boost mailing list: http://boost.2283326.n4.nabble.com/How-to-design-proper-release-of-a-boost-asio-socket-or-wrapper-thereof-td4693442.html

推荐答案

虽然其他人的回答与此答案的下半部分相似,但看来我能找到的最完整的答案来自在Boost Mailing上询问相同的问题列表.

While others have answered similarly to the second half of this answer, it seems the most complete answer I can find, came from asking the same question on the Boost Mailing list.

在这里我将进行总结,以帮助将来通过搜索到达此处的人.

I will summarize here in order to assist those that arrive here from a search in the future.

有2个选项

1)关闭套接字以取消任何未完成的io,然后在io_service上发布用于断开连接后逻辑的回调,并在套接字断开连接时回调服务器类.然后,它可以安全地释放连接.只要只有一个线程调用io_service :: run,那么在进行回调时,其他异步操作将已经被解决.但是,如果有多个调用io_service :: run的线程,那么这是不安全的.

1) Close the socket in order to cancel any outstanding io and then post a callback for the post-disconnection logic on the io_service and let the server class be called back when the socket has been disconnected. It can then safely release the connection. As long as there was only one thread that had called io_service::run, then other asynchronous operations will have been already been resolved when the callback is made. However, if there are multiple threads that had called io_service::run, then this is not safe.

2)正如其他人在他们的答案中指出的那样,使用shared_ptr来管理连接生存期,使用出色的io操作来保持连接存活是可行的.如果需要,我们可以对连接使用collection_wet_ptr以便访问它们.后者是关于该主题的其他帖子所忽略的花絮.

2) As others have been pointing out in their answers, using the shared_ptr to manage to connections lifetime, using outstanding io operations to keep them alive, is viable. We can use a collection weak_ptr to the connections in order to access them if we need to. The latter is the tidbit that had been omitted from other posts on the topic which confused me.

这篇关于如何设计boost :: asio套接字或其包装的正确释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆