c++ - 使用 asio 和 C++11 接受或接收时优雅地停止线程以进行阻塞或非阻塞

标签 c++ linux multithreading c++11 boost-asio

我正在为 tcp 服务器使用 asio,我也计划为线程使用 C++11 std。我的最终目标是在 Linux 上运行此应用程序,但我首先使用 Visual Studio 2015 在 Windows 上对其进行测试。

首先我使用阻塞,所以我发现有人讨论如何停止等待接受的线程。有 C++11 之前的解决方案,例如管道和选择。我正在寻找 asio 方式。

    asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));
    backAcceptor = &acceptor;
    tcp::socket socket(io_service);

    asio::error_code ec;
    acceptor.accept(socket, &ec);

第二种方法是使用异步,但我更喜欢只使用 asio header 。编译提示 asio::placeholder 没有这个成员,但根据评论,应用了解决方案:

    asio::async_write(socket_, asio::buffer(message_),
        std::bind(&tcp_connection::handle_write, shared_from_this(),
            std::placeholders::_1,
            std::placeholders::_2
            ));

run() 仍然阻塞在那里。我正在寻找从 main 恢复此线程的方法。

    asio::io_service io_service;
    tcp_server server(io_service);
    io_service.run();

第三种方式,设置超时here .但这并不能阻止我接受。另外,答案是在 2012 年。我希望现在有新的解决方案。

更新

为了测试场景,我首先有一个线程在同步 accept() 或异步 run() 时阻塞。当线程运行时,main 等待 2 秒,然后尝试停止线程。然后我使用 join 等待线程完成。

对于第一个方法“同步”,我尝试使用 acceptor.cancel() 并且线程到达了连接。这是正确的方法吗?

第二种方法“异步”,虽然我还不清楚如何正式停止这个线程,但我成功地使用 io_service.stop() 实际取消了它。

请告诉我我的解决方案是否正确,我会继续尝试不同的解决方案。

最佳答案

我碰巧用 run_one 和没有线程的非典型方法玩过,它特别允许您超时个别“非异步”操作:

事实上,您确实发布了异步操作,但随后您调用了带有超时的 await_operation:

async_connect(socket, ip::tcp::resolver(ioservice).resolve({address, port}), raise());
await_socket(std::chrono::seconds(6));

这相当于同步connect但是可能会超时。没有线程、阻塞 run() 或其他小狗受到伤害。

查看演示的链接答案


附言。如果您不想要与 std::chrono 配合良好的 high_resolution_timer,请将 deadline_timerposix_time 一起使用p>

关于c++ - 使用 asio 和 C++11 接受或接收时优雅地停止线程以进行阻塞或非阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33459322/

相关文章:

C++ 程序未正确链接到 .so 文件

c++ - 调试和发布版本中的奇怪执行时间

c++ - 如果我想调整缓冲区大小,是否需要 glDeleteBuffers/glGenBuffers?

c++ - 写入多个文件时崩溃

linux - SQLite:Fsyncing with journal_mode = wal and synchronous = normal

linux - 从命令行将文件添加到 MSI?

python - 如何将 django-evolution 目录添加到我的 Python 路径 - Ubuntu

java - 为什么线程会按这个顺序执行?

Java Servlets 线程模型

c++ - 如何使用 boost::thread_group 使用多客户端服务器?