试图理解提升示例 httpserver3。 shared_ptr 重置方法不清楚

Posted

技术标签:

【中文标题】试图理解提升示例 httpserver3。 shared_ptr 重置方法不清楚【英文标题】:trying to understand boost example httpserver3. Something unclear with shared_ptr reset method 【发布时间】:2013-09-14 18:50:09 【问题描述】:

我正在使用 boost 示例 httpserver3:http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/examples.html#boost_asio.examples.http_server_3

我不能清楚地理解调用new_connection_的reset方法时会发生什么

void server::start_accept()

  new_connection_.reset(new connection(io_service_, request_handler_));
  acceptor_.async_accept(new_connection_->socket(),
      boost::bind(&server::handle_accept, this,
        boost::asio::placeholders::error));


void server::handle_accept(const boost::system::error_code& e)

  if (!e)
  
    new_connection_->start();
  
    std::cout<<"handle_accept"<<std::endl;
  start_accept();

我知道“重置”会导致之前的对象被删除,如文档所述。 如果服务器对象在前一个连接对象正在处理它的请求时接受一个新连接会发生什么?之前的连接会被立即销毁还是会收到错误并退出?

void connection::handle_read(const boost::system::error_code& e,
    std::size_t bytes_transferred)

  if (!e)
  
    boost::tribool result;
    boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
        request_, buffer_.data(), buffer_.data() + bytes_transferred);

    if (result)
    
      request_handler_.handle_request(request_, reply_);
      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    
    else if (!result)
    
      reply_ = reply::stock_reply(reply::bad_request);
      boost::asio::async_write(socket_, reply_.to_buffers(),
          strand_.wrap(
            boost::bind(&connection::handle_write, shared_from_this(),
              boost::asio::placeholders::error)));
    
    else
    
      socket_.async_read_some(boost::asio::buffer(buffer_),
          strand_.wrap(
            boost::bind(&connection::handle_read, shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)));
    
  

  // If an error occurs then no new asynchronous operations are started. This
  // means that all shared_ptr references to the connection object will
  // disappear and the object will be destroyed automatically after this
  // handler returns. The connection class's destructor closes the socket.


void connection::handle_write(const boost::system::error_code& e)

  if (!e)
  
    // Initiate graceful connection closure.
    boost::system::error_code ignored_ec;
    socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
  

  // No new asynchronous operations are started. This means that all shared_ptr
  // references to the connection object will disappear and the object will be
  // destroyed automatically after this handler returns. The connection class's
  // destructor closes the socket.
 

【问题讨论】:

【参考方案1】:

啊,shared_from_this() 的魔力。你错过了这部分代码:

void connection::start()

  socket_.async_read_some(boost::asio::buffer(buffer_),
      strand_.wrap(
        boost::bind(&connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred)));

会发生什么:

    server::handle_accept() 致电new_connection_-&gt;start()connection::start() 安排读取操作,并通过这样做,使用 shared_from_this() 调用创建原始共享指针的副本。 现在 server::handle_accept() 打电话给server::start_accept()server::start_accept()reset() 原来的共享指针,但是 ASIO 服务有它的副本,所以只要连接的回调继续使用 shared_from_this() 调度更多操作,连接就不会被破坏(因为会有至少一个共享指针仍指向堆分配的connection 对象)。

【讨论】:

以上是关于试图理解提升示例 httpserver3。 shared_ptr 重置方法不清楚的主要内容,如果未能解决你的问题,请参考以下文章

Scala / Lift - 试图理解 Lift 同时声称使用有效 html 和提升倾向:渲染中的标签和标签重写

试图理解 ML 上的示例脚本

试图理解一个基本的 WordCount MapReduce 示例

试图编译生成 sha1 哈希的程序

openssl evp 哈希算法(md5,sha1,sha256)

借用gcc源码中的sha1.c计算HMAC_SHA1