簡體   English   中英

提升Asio,多線程和多個io_service

[英]Boost Asio, Multiple threads and multiple io_service

我想開發一個服務器使用多個線程和多個io_service實例(每個線程使用一個io_service實例)來監聽端口。 對於每個io_service實例,我創建了一個相應的boost :: asio :: ip :: tcp :: acceptor對象。 我試試這段代碼:

 using namespace boost::asio;
    ...
    io_service io_service_;
    io_service io_service_1;

    ip::tcp::acceptor* acceptor_;
    acceptor_ = new ip::tcp::acceptor(io_service_);
    ip::tcp::endpoint ep( ip::tcp::v4(), LISTEN_PORT);
    acceptor_->open(ep.protocol());
    acceptor_->bind(ep);
    acceptor_->listen();

    ip::tcp::acceptor* acceptor_1;
    acceptor_1 = new ip::tcp::acceptor(io_service_1);
    acceptor_1->open(ep.protocol());
    acceptor_1->bind(ep);
    acceptor_1->listen();
    ...

    boost::thread th( boost::bind(&io_service::run, &io_service_));
    boost::thread th( boost::bind(&io_service::run, &io_service_1));
    ...

運行時會顯示錯誤對話框:

boost :: exception_detail :: clone_impl <boost :: exception_detail :: error_info_injector>在內存位置0x001FF704。

你能幫助我如何使用多個線程制作服務器,每個線程使用一個io_service實例嗎?

更新:正如我在Boost.Asio C ++網絡編程中所讀到的,有3種方法可以使用帶線程的io_service:

  1. 單線程,帶有一個io_service和一個處理程序線程(運行io_service :: run()的線程)
  2. 具有單個io_service實例和多個處理程序線程的多線程
  3. 具有多個io_service實例和多個線程的多線程

我可以實現案例1和2.但是對於案例3,我不知道如何實現它來處理許多並發連接,我應該使用1個線程來處理1個io_service(如上所述)? 案例3是否具有比案例2更好的性能(可以處理更多並發連接)?

您可以使用多個線程,但需要使用1個接受器作為端口。

IO服務是線程安全的,因此您可以在許多線程上使用一個服務。

您甚至可以擁有多個io服務,沒問題。 您不能將多個接收器綁定到同一個端口(除非您綁定到不同的邏輯網絡接口,但是,那不是真正“相同的端口”)。

#include <boost/asio.hpp>
#include <boost/thread.hpp>

using namespace boost::asio;
using namespace boost;

int main() {
    io_service io_service_;

    ip::tcp::acceptor acceptor_(io_service_, { {}, 6767 });
    acceptor_.bind({ ip::tcp::v4(), 6767 });

    boost::thread_group tg;
    for (unsigned i = 0; i < thread::hardware_concurrency(); ++i)
        tg.create_thread(boost::bind(&io_service::run, &io_service_));

    // ...
    //
    tg.join_all();
}

您只能讓一個acceptor在給定端口上進行偵聽。 如果要使用一個端口處理多個客戶端,則需要在acceptor上設置選項reuse_address 這樣,傳遞給async_accept()的套接字將使用不同的端口,讓您的偵聽端口可以自由接受來自另一個客戶端的連接。

boost::asio::io_service ios_;
boost::asio::ip::tcp::acceptor acceptor_(ios_);

void handle_client(boost::shared_pointer<boost::asio::ip::tcp::socket> sock);
void start_accept();

int main() {
    boost::asio::ip::tcp::endpoint ep(ip::tcp::v4(), LISTEN_PORT);
    acceptor_.open(ep.protocol());
    acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
    acceptor_.bind(ep);
    acceptor_.listen();
    boost::thread_group threads;
    for (int i = 0; i < NUM_WORKER_THREADS; ++i) {
        threads.create_thread(boost::bind(&io_service::run, &ios_));
    }
    start_accept();
    threads.join_all();
}

void start_accept() {
    boost::shared_pointer<boost::asio::ip::tcp::socket> sock(ios_);
    acceptor_.async_accept(*sock, boost::bind(handle_client, sock));
}

void handle_client(boost::shared_pointer<boost::asio::ip::tcp::socket> sock) {
    start_accept();
    // talk to the client
}

有關更完整的示例,請參閱Boost的HTTP服務器示例。

暫無
暫無

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

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