【问题标题】:Boost::ASIO: using tcp::socket on multiple threadsBoost::ASIO:在多个线程上使用 tcp::socket
【发布时间】:2023-03-06 12:56:01
【问题描述】:

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

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

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(...)) 读取(阻塞)数据,而另一个线程需要使用该套接字写入(阻塞)数据。

我试图使用同一个 asio::io_service 对象构造两个 tcp::socket 对象,但这不起作用。

有什么想法吗?

【问题讨论】:

  • “行不通”是什么意思?
  • “在至少两个线程上使用这个套接字的功能”——你的意思是同一个客户端的连接?
  • 每个tcp::socket 对象都应该引用一个离散的本机套接字。您能否解释一下为什么要将两个 tcp::socket 对象用于单个 TCP 连接?
  • @TannerSansbury 我想要两个 tcp::socket 指代同一个离散的本机套接字。我想要这个,因为我不能在两个线程之间共享现有的。
  • @Marius 为什么不能通过引用shared_ptr 等在两个线程之间共享单个tcp::socket 对象? tcp::socket 对象旨在获取本机套接字的所有权。有两个 tcp::socket 对象声称拥有同一个本机套接字的所有权可能会增加不必要的复杂性。

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


【解决方案1】:

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

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

Asio 1.4.0 / Boost 1.37

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    相关资源
    最近更新 更多