【问题标题】:Stopping threaded server loop using Boost::Asio使用 Boost::Asio 停止线程服务器循环
【发布时间】:2011-06-09 19:20:19
【问题描述】:

我正在为一个更大的软件开发一个小型服务器循环,但它没有按我的意愿工作。

当用户输入“.quit”时,我希望软件停止这个线程服务器循环:

try {

while (true) {
      acceptor.accept(socket);
      const size_t buffersize = 1024;
      char data[buffersize+1] = {0};
      data[socket.read_some(boost::asio::buffer(data,buffersize))] = '\0'; // Write data & place terminator
      boost::thread asyncWriting(boost::bind( &myClass::writeToFile, this ));
      socket.close();
}

} catch(const boost::system::system_error& e) {
    cout << "Boost System Error: " << e.what() << endl;
}

我通过以下方式启动线程:

serverThread = boost::shared_ptr<boost::thread>( new boost::thread(boost::bind( &myClass::startServer, this )) );

但是我在停止“服务器”时遇到了问题。无论我是中断线程、关闭套接字和/或接受器还是只是中断程序 Boost 都会抛出错误:

 Bad file descriptor

它不会每次都发生,但经常发生,我想解决这个问题,而不是忽略它。

你能帮我如何关闭它clean吗?

【问题讨论】:

  • 如果您可以附加一个调试器并告诉我们异常是在哪里引发的,那将会很有帮助。有多种 asio 方法可以抛出错误代码为boost::system::errc::bad_file_descriptorboost::system::system_error

标签: c++ boost-asio boost-thread


【解决方案1】:

服务器通常使用异步方法编写

  • async_accept
  • async_read
  • async_write

在这种情况下,关闭所有未决异步操作的建议技术是 stop io_service 的事件处理循环。注意要特别注意~io_servicedocumentation

描述的销毁顺序 以上允许程序简化 他们的资源管理通过使用 shared_ptr。一个物体在哪里 生命周期与 a 的生命周期相关联 连接(或其他一些序列 异步操作),一个 shared_ptr 到对象将被绑定到 所有异步的处理程序 与之相关的操作。

根据您发布的问题所在的有限代码,这对我来说并不明显,我建议发布更多代码或运行您在valgrind 下拥有的代码,因为它很可能会暴露一些问题。

几天前我回复了similar question,您可能会觉得有用

【讨论】:

  • 嗨,山姆,感谢您的回答!我今天也在我的谷歌搜索中找到了这个问题,但我不确定我是否应该使用这种方法。但是我会看一下,使其异步并在这里写下我的经验。
  • 完美运行。知道您可以绑定接受器并在 io_service.stop() 的帮助下安全地结束它是很重要的;
  • @Paul 太棒了!很高兴能帮到你。
  • 嗨,Sam,我在切换到异步接受器操作后检查了 valgrind,并使用此示例 (boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/echo/…) 作为模式。事实证明,我有一些泄漏,因为我分配了会话(新会话(io_service);)并且从不释放它们,因为它们在异步线程中丢失和/或它们的指针丢失。这就是为什么我的过程正在成长和成长。我该如何解决?
  • @Paul 最好提出一个新问题并在其中发布您的新代码。用boost-asiovalgrind 标记它。
猜你喜欢
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多