【问题标题】:`boost::asio` `async_resolve` hangs on Linux, what may be a reason?`boost::asio` `async_resolve` 在 Linux 上挂起,可能是什么原因?
【发布时间】:2016-02-02 11:09:49
【问题描述】:

我编写了复杂的 TCP/IP 客户端应用程序,它会生成大量的传出 TCP 连接。我尝试使用boost::asio 作为 C++ 中的可移植 TCP/IP 网络实现。

我发现了以下问题。见代码:

int main(int argc, char *argv[])
{
    using namespace boost::asio;
    io_service io;
    thread ioThread([&io]()
    {
        while (true)
        {
            if (!io.run())
                this_thread::sleep_for(seconds(1));
        }
    });
    ioThread.detach();
    ip::tcp::resolver r(io);
    ip::tcp::resolver::query q("www.boost.org", "80");
    atomic<bool> done(false);
    r.async_resolve(q, [&done](const boost::system::error_code& error, ip::tcp::resolver::iterator iterator)
    {
        if (error)
            wprintf(W("Error!\r\n"));
        else
        {
            ip::tcp::resolver::iterator end;
            while (iterator != end)
            {
                ip::tcp::endpoint endpoint = *iterator++;
                std::cout << endpoint << std::endl;
            }
        }
        done.store(true);
    });
    while (!done.load())
        this_thread::sleep_for(seconds(1));
    return 0;
}

此代码运行后台线程来执行io_service::run 方法。假设我们将有多个套接字使用这个io_service 来执行异步操作。

在 Windows (Visual Studio 2013 x64) 上,此代码运行良好并打印端点地址。

在带有 boost 1.60 和 clang 3.4.2 的 CentOS Linux 6 上它挂起。

有什么想法为什么async_resolve 永远不会完成吗?

【问题讨论】:

  • 您包含的代码无法编译,minimal reproducible example.
  • 代码编译没有问题,当然,如果你添加了所需的头文件。在 VS 2013 和 clang 3.4.2 上测试。

标签: c++ linux sockets boost tcp


【解决方案1】:

我认为问题在于您的线程函数没有重置boost::asio::io_service 实例。 documentation 说:

[reset()] 必须在 run()、run_one()、poll() 或 poll_one() 函数的任何第二组或以后的调用集之前调用 当这些函数的先前调用由于 io_service 被停止或用尽。

在您的程序中,boost::asio::io_service 实例返回是因为它的工作用完了,所以如果不先调用 reset(),就不能再次调用它(即在下一次循环迭代中)。

您的程序中有一个竞态条件,它会使其在某些情况下工作,而在某些情况下不工作。如果解析器操作在第一次时间run() 被调用时及时排队,那么它将起作用。如果没有,那么它将无法正常工作。这应该可以解释为什么它可以在一个操作系统上运行,而不能在另一个操作系统上运行。

与您的问题没有直接关系的另一个注意事项是,您的线程函数在循环中调用run() 有点尴尬。如果要控制run() 的持续时间,使用io_service::work 可能是更好的方法。

【讨论】:

    猜你喜欢
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 2021-09-01
    相关资源
    最近更新 更多