Boost asio async_accept memory leak问题分析

原创 2013年12月05日 11:14:35

可以看下stackflow上的问题描述:

Using boost::asio i use async_accept to accept connections. This works good, but there is one issue and i need a suggestion how to deal with it. Using typical async_accept:

  Listener::Listener(int port)
        : acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), port))
        , socket(io) {
          start_accept();
  }

  void Listener::start_accept() {
      Request *r = new Request(io);
      acceptor.async_accept(r->socket(), 
        boost::bind(&Listener::handle_accept, this, r, placeholders::error));
  }

Works fine but there is a issue: Request object is created with plain new so it can memory "leak". Not really a leak, it leaks only at program stop, but i want to make valgrind happy.

Sure there is an option: i can replace it with shared_ptr, and pass it to every event handler. This will work until program stop, when asio io_service is stopping, all objects will be destroyed and Requestwill be free'd. But this way i always must have an active asio event for Request, or it will be destroyed! I think its direct way to crash so i dont like this variant, too.

UPD Third variant: Listener holds list of shared_ptr to active connections. Looks great and i prefer to use this unless some better way will be found. The drawback is: since this schema allows to do "garbage collection" on idle connects, its not safe: removing connection pointer from Listener will immediately destroy it, what can lead to segfault when some of connection's handler is active in other thread. Using mutex cant fix this cus in this case we must lock nearly anything.

Is there a way to make acceptor work with connection management some beautiful and safe way? I will be glad to hear any suggestions.

问题在于如果程序关掉,连接来了,new 出来的tcp::socket没有被释放。

所以官方文档有讲到:

On destruction, the io_service performs the following sequence of operations:

  • For each service object svc in the io_service set, in reverse order of the beginning of service object lifetime, performs svc->shutdown_service().
  • Uninvoked handler objects that were scheduled for deferred invocation on the io_service, or any associated strand, are destroyed.
  • For each service object svc in the io_service set, in reverse order of the beginning of service object lifetime, performs delete static_cast<io_service::service*>(svc).
Remarks

The destruction sequence described above permits programs to simplify their resource management by using shared_ptr<>. Where an object's lifetime is tied to the lifetime of a connection (or some other sequence of asynchronous operations), a shared_ptr to the object would be bound into the handlers for all asynchronous operations associated with it. This works as follows:

  • When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and all shared_ptr references to the objects are destroyed.
  • To shut down the whole program, the io_service function stop() is called to terminate any run() calls as soon as possible. The io_service destructor defined above destroys all handlers, causing all shared_ptr references to all connection objects to be destroyed.
提倡用智能指针。其实可以嘛。

boost::ASIO的异步方式

 嗯?异步方式好像有点坐不住了,那就请异步方式上场,大家欢迎...大家好,我是异步方式和同步方式不同,我从来不花时间去等那些龟速的IO操作,我只是向系统说一声要做什么,然后就可以做其它事去了。如果系统...
  • zhuky
  • zhuky
  • 2010年03月10日 13:50
  • 13919

Socket的异步接收方法【AcceptAsync】之【SocketAsyncEventArgs】

最近在学习socket服务端的作成流程,没有资料,没有参考,然后自己就瞎捉摸着,左改改右写写, 碰到了很多问题,也总结了些心得,然后就打算记录下来:    对于这个AcceptAsync这...
  • crazyliyang
  • crazyliyang
  • 2013年09月23日 17:17
  • 2857

gen_tcp async accept大致流程

http://bachmozart.iteye.com/blog/482507 erlang 调用 gen_tcp:accept时是会阻塞的,包括后续的gen_tcp:recv也是,但是这个阻塞...
  • mituan1234567
  • mituan1234567
  • 2016年08月27日 19:37
  • 260

Erlang网络编程中的一个特别的函数prim_inet:async_accept/2

为了研究怎么用Erlang写一个游戏服务器,我很幸运的下到了一份英雄远征的服 务器Erlang源码,这两天花了点时间看代码,其中看到做TCP的accept动作时,它 是用的一个函数prim_ine...
  • lile1234_show
  • lile1234_show
  • 2013年12月25日 17:18
  • 5595

prim_inet:async_accept

gen_tcp:accept Accepts an incoming connection request on a listen socket. Socket must be a socket r...
  • aaaajw
  • aaaajw
  • 2016年06月21日 12:58
  • 1487

boost::ASIO的同步方式和异步方式

http://blog.csdn.net/zhuky/article/details/5364574 http://blog.csdn.net/zhuky/article/details/53646...
  • damonxx
  • damonxx
  • 2016年09月13日 09:31
  • 3114

accept的一个小陷阱

先看下面的代码: 监听127.0.0.1 : 5563 ,如果有连接,就输出这个客户端的IP、端口和连接描述符。 #include #include int main(int argc,ch...
  • lv_xinmy
  • lv_xinmy
  • 2013年05月30日 17:52
  • 1786

boost 异步IO 服务端实例代码

/* * tcp_async_echo_server.cpp * * Created on: Dec 16, 2013 3:17:37 PM * Author: Jeffrey C...
  • u011676589
  • u011676589
  • 2013年12月17日 17:24
  • 996

boost:asio的同步方式和异步方式

http://blog.csdn.net/byrsongqq/article/details/6253435   Boost.Asio是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手...
  • niitlcj
  • niitlcj
  • 2012年03月09日 10:23
  • 3727

【Boost】boost库asio详解8——几个TCP的简单例子

摘于boost官网的几个例子, 做了点小修改, 笔记之. 同步客户端 void test_asio_synclient() { typedef boost::asio::io_service...
  • huang_xw
  • huang_xw
  • 2013年01月18日 22:56
  • 26334
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Boost asio async_accept memory leak问题分析
举报原因:
原因补充:

(最多只允许输入30个字)