簡體   English   中英

Boost.Asio async_write 和鏈

[英]Boost.Asio async_write and strands

我正在使用一個鏈來避免使用Boost.Asio在 TCP 服務器上並發寫入。 但它似乎只會阻止處理程序的並發執行。

事實上,如果我連續執行兩個async_write ,一個有一個非常大的數據包,另一個有一個非常小的數據包,wireshark 會顯示交錯。 作為async_write由多個調用async_write_some ,好像是我的第二個寫的處理程序被允許第一次呼叫的兩個處理程序之間執行。 這對我來說非常糟糕。

Wireshark 輸出:[Packet 1.1] [Packet 1.2] [ Packet 2 ] [Packet 1.3] ... [Packet 1.x]

struct Command
{
    // Header
    uint64_t ticket_id; // UUID
    uint32_t data_size; // size of data

    // data
    std::vector<unsigned char> m_internal_buffer;
}
typedef std::shared_ptr<Command> command_type;
void tcp_server::write(command_type cmd)
{
    boost::asio::async_write(m_socket, boost::asio::buffer(cmd->getData(), cmd->getTotalPacketSize()),
        boost::asio::bind_executor(m_write_strand,
            [this, cmd](const boost::system::error_code& error, std::size_t bytes_transferred)
            {
                if (error)
                {
                   // report
                }
            }
        )
    );
}

和主要的:

int main()
{
    tcp_server.write(big_packet); // Packet 1 = 10 MBytes !
    tcp_server.write(small_packet); // Packet 2 = 64 kbytes
}

在我的情況下,股線不合適嗎?

PS:我在這里看到了那個接近的話題但在我看來它沒有涵蓋相同的用例。

您必須確保您的異步操作是從鏈啟動的。 您的代碼目前並未顯示這種情況。 希望這會有所幫助,否則,發布MCVE

所以例如

void tcp_server::write(command_type cmd)
{
    post(m_write_strand, [this, cmd] { this->do_write(cmd); });
}

從你的問題代碼組成一個 MCVE:

住在 Coliru

#include <boost/asio.hpp>
using boost::asio::ip::tcp;
using Executor = boost::asio::thread_pool::executor_type;

struct command {
    char const* getData()            const { return ""; }
    size_t      getTotalPacketSize() const { return 1;  }
};
using command_type = command*;

struct tcp_server {
    tcp_server(Executor ex) : m_socket(ex), m_write_strand(ex)
    {
        // more?
    }
    void write(command_type cmd);
    void do_write(command_type cmd);

    tcp::socket m_socket;
    boost::asio::strand<Executor> m_write_strand;
};

void tcp_server::write(command_type cmd)
{
    post(m_write_strand, [this, cmd] { this->do_write(cmd); });
}

void tcp_server::do_write(command_type cmd)
{
    boost::asio::async_write(
        m_socket,
        boost::asio::buffer(cmd->getData(), cmd->getTotalPacketSize()),
        bind_executor(m_write_strand,
                      [/*this, cmd*/](boost::system::error_code error,
                                      size_t bytes_transferred) {
                          if (error) {
                              // report
                          }
                      }));
}

int main() {
    boost::asio::thread_pool ioc;
    tcp_server tcp_server(ioc.get_executor());

    command_type big_packet{}, small_packet{};
    tcp_server.write(big_packet);   // Packet 1 = 10 MBytes !
    tcp_server.write(small_packet); // Packet 2 = 64 kbytes

    ioc.join();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM