【C++】析构函数下发任务注意事项

【C++】析构函数下发任务注意事项,第1张

在使用时间循环驱动时,往往在类外面启动了一个EventLoop,来驱动事件的处理。
依托该EventLoop的类在析构时,有时候需要进行一些善后处理,这些处理往往就将任务放入到了EventLoop队列中。
注意:在丢进EventLoop丢列的任务,一定不要使用正在析构类的函数对象,一定要确保丢入的函数对象在运行时是合法的。

下面以muduo中TcpClient源代码进行说明

namespace muduo
{
namespace net
{
namespace detail
{

void removeConnection(EventLoop* loop, const TcpConnectionPtr& conn)
{
  loop->queueInLoop(std::bind(&TcpConnection::connectDestroyed, conn));
}

void removeConnector(const ConnectorPtr& connector)
{
  //connector->
}

}  // namespace detail
}  // namespace net
}  // namespace muduo



TcpClient::~TcpClient()
{
  LOG_INFO << "TcpClient::~TcpClient[" << name_
           << "] - connector " << get_pointer(connector_);
  TcpConnectionPtr conn;
  bool unique = false;
  {
    MutexLockGuard lock(mutex_);
    unique = connection_.unique();
    conn = connection_;
  }
  if (conn)
  {
    assert(loop_ == conn->getLoop());
    // FIXME: not 100% safe, if we are in different thread
    CloseCallback cb = std::bind(&detail::removeConnection, loop_, _1);
    loop_->runInLoop(
        std::bind(&TcpConnection::setCloseCallback, conn, cb));
    if (unique)
    {
      conn->forceClose();
    }
  }
  else
  {
    connector_->stop();
    // FIXME: HACK
    loop_->runAfter(1, std::bind(&detail::removeConnector, connector_));
  }
}

1、CloseCallback cb = std::bind(&detail::removeConnection, loop_, _1);
放入的是全局函数对象
2、std::bind(&TcpConnection::setCloseCallback, conn, cb)
放入的是函数对象是shared_ptr,只要有对对象的引用,就能保证对象不能被释放

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/756135.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-30
下一篇 2022-04-30

发表评论

登录后才能评论

评论列表(0条)

保存