Boost :: ASIO:在多个线程上使用tcp :: socket

时间:2016-05-27 13:48:27

标签: c++ multithreading boost tcp boost-asio

所以我有一个TCP服务器,它等待特定端口连接客户端。

如果有一个客户端连接,我用tcp::socket构造一个asio::io_service对象,然后我接受该套接字。例如:

void Gateway::server(boost::asio::io_service& io_service, unsigned short port) {
    tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
    bool UARTToWiFiGatewayStarted = false;

    for (;;) {
        tcp::socket sock(io_service);

        a.accept(sock);

        std::thread(startWiFiToUARTSession, std::move(sock)).detach();

        if(false == UARTToWiFiGatewayStarted) {
            //std::thread(startUARTToWifiSession, std::move(sock2)).detach();
            UARTToWiFiGatewayStarted = true;
        }
    }
}

现在我想在至少两个线程上使用这个套接字的功能,一个线程将从套接字(read_some(...))读取(阻塞),另一个线程需要写入(阻塞)数据使用那个插座。

我尝试使用相同的tcp::socket对象构建两个asio::io_service个对象,但这些对象无法正常工作。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

socket对象旨在获取本机套接字的所有权,并提供RAII语义来管理本机套接字。因此,单个socket对象应该引用离散的本机套接字。否则,底层套接字的状态可能会意外更改。

虽然socket文档指定在单个共享socket上进行并发调用是不安全的,但revision history会记录此规则的例外情况。从Asio 1.4.0 / Boost 1.37开始,如果OS支持,同步socket对象上同时进行的读取,写入,接受和连接操作都是线程安全的:< / p>

  

Asio 1.4.0 / Boost 1.37

     
      
  • ...
  •   
  • 同步读取,写入,接受和连接操作现在是线程安全的(这意味着现在允许它在单个套接字上执行并发同步操作,如果操作系统支持的话)。
  •   
  • ...
  •   

在这种情况下,如果操作系统支持,从一个线程中的套接字同步读取,并在另一个线程中同时写入同一个套接字是线程安全的。