久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

Boost::asio - 如何中斷被阻塞的 tcp 服務器線程?

Boost::asio - how to interrupt a blocked tcp server thread?(Boost::asio - 如何中斷被阻塞的 tcp 服務器線程?)
本文介紹了Boost::asio - 如何中斷被阻塞的 tcp 服務器線程?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我正在開發一個多線程應用程序,其中一個線程充當從客戶端接收命令的 tcp 服務器.該線程使用 Boost 套接字和接受器等待客戶端連接,從客戶端接收命令,將命令傳遞給應用程序的其余部分,然后再次等待.代碼如下:

I'm working on a multithreaded application in which one thread acts as a tcp server which receives commands from a client. The thread uses a Boost socket and acceptor to wait for a client to connect, receives a command from the client, passes the command to the rest of the application, then waits again. Here's the code:

void ServerThreadFunc()
{
    using boost::asio::ip::tcp;
    boost::asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port_no));

    for (;;)
    {
        //  listen for command connection
        tcp::socket socket(io_service);
        acceptor.accept(socket);

        //  connected; receive command
        boost::array<char,256> msg_buf;
        socket.receive(boost::asio::buffer(msg_buf));

        //  do something with received bytes here
    }
}

該線程的大部分時間都花在對acceptor.accept() 的調用上.目前,線程僅在應用程序退出時終止.不幸的是,這會在 main() 返回后導致崩潰 - 我相信是因為在單例被銷毀后線程試圖訪問應用程序的日志單例.(老實說,我剛來的時候就是這樣.)

This thread spends most of its time blocked on the call to acceptor.accept(). At the moment, the thread only gets terminated when the application exits. Unfortunately, this causes a crash after main() returns - I believe because the thread tries to access the app's logging singleton after the singleton has been destroyed. (It was like that when I got here, honest guv.)

如何在應用程序退出時干凈地關閉此線程?我讀到可以通過從另一個線程關閉套接字來中斷原始套接字上的阻塞 accept() 調用,但這似乎不適用于 Boost 套接字.我嘗試使用 Boost 異步 tcp 回顯服務器示例,但這似乎只是交換了對 acceptor::accept() 的阻塞調用來對 io_service 的阻塞調用::run(),所以我遇到了同樣的問題:一個無法中斷的阻塞調用.有什么想法嗎?

How can I shut this thread down cleanly when it's time for the application to exit? I've read that a blocking accept() call on a raw socket can be interrupted by closing the socket from another thread, but this doesn't appear to work on a Boost socket. I've tried converting the server logic to asynchronous i/o using the Boost asynchronous tcp echo server example, but that just seems to exchange a blocking call to acceptor::accept() for a blocking call to io_service::run(), so I'm left with the same problem: a blocked call which I can't interrupt. Any ideas?

推薦答案

總之,有兩個選擇:

  • 將代碼更改為異步(acceptor::async_accept()async_read),通過 io_service::run() 在事件循環中運行code>,并通過 io_service::stop() 取消.
  • 強制阻塞調用以較低級別的機制(例如信號)中斷.
  • Change code to be asynchronous (acceptor::async_accept() and async_read), run within the event loop via io_service::run(), and cancel via io_service::stop().
  • Force blocking calls to interrupt with lower level mechanics, such as signals.

我會推薦第一個選項,因為它更易于攜帶且更易于維護.要理解的重要概念是 io_service::run() 只會在有待處理的工作時阻塞.當 io_service::stop() 被調用,它會嘗試使 io_service::run() 上阻塞的所有線程盡快返回;它不會中斷同步操作,例如 acceptor::accept()socket::receive(),即使同步操作在事件循環中被調用.需要注意的是,io_service::stop() 是一個非阻塞調用,因此與 io_service::run() 上阻塞的線程同步必須使用另一個機制,例如 thread::join().

I would recommend the first option, as it is more likely to be the portable and easier to maintain. The important concept to understand is that the io_service::run() only blocks as long as there is pending work. When io_service::stop() is invoked, it will try to cause all threads blocked on io_service::run() to return as soon as possible; it will not interrupt synchronous operations, such as acceptor::accept() and socket::receive(), even if the synchronous operations are invoked within the event loop. It is important to note that io_service::stop() is a non-blocking call, so synchronization with threads that were blocked on io_service::run() must use another mechanic, such as thread::join().

這是一個運行 10 秒并偵聽端口 8080 的示例:

Here is an example that will run for 10 seconds and listens to port 8080:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <iostream>

void StartAccept( boost::asio::ip::tcp::acceptor& );

void ServerThreadFunc( boost::asio::io_service& io_service )
{
  using boost::asio::ip::tcp;
  tcp::acceptor acceptor( io_service, tcp::endpoint( tcp::v4(), 8080 ) );

  // Add a job to start accepting connections.
  StartAccept( acceptor );

  // Process event loop.
  io_service.run();

  std::cout << "Server thread exiting." << std::endl;
}

void HandleAccept( const boost::system::error_code& error,
                   boost::shared_ptr< boost::asio::ip::tcp::socket > socket,
                   boost::asio::ip::tcp::acceptor& acceptor )
{
  // If there was an error, then do not add any more jobs to the service.
  if ( error )
  {
    std::cout << "Error accepting connection: " << error.message() 
              << std::endl;
    return;
  }

  // Otherwise, the socket is good to use.
  std::cout << "Doing things with socket..." << std::endl;

  // Perform async operations on the socket.

  // Done using the socket, so start accepting another connection.  This
  // will add a job to the service, preventing io_service::run() from
  // returning.
  std::cout << "Done using socket, ready for another connection." 
            << std::endl;
  StartAccept( acceptor );
};

void StartAccept( boost::asio::ip::tcp::acceptor& acceptor )
{
  using boost::asio::ip::tcp;
  boost::shared_ptr< tcp::socket > socket(
                                new tcp::socket( acceptor.get_io_service() ) );

  // Add an accept call to the service.  This will prevent io_service::run()
  // from returning.
  std::cout << "Waiting on connection" << std::endl;
  acceptor.async_accept( *socket,
    boost::bind( HandleAccept,
      boost::asio::placeholders::error,
      socket,
      boost::ref( acceptor ) ) );
}

int main()
{
  using boost::asio::ip::tcp;

  // Create io service.
  boost::asio::io_service io_service;

  // Create server thread that will start accepting connections.
  boost::thread server_thread( ServerThreadFunc, boost::ref( io_service ) );

  // Sleep for 10 seconds, then shutdown the server.
  std::cout << "Stopping service in 10 seconds..." << std::endl;
  boost::this_thread::sleep( boost::posix_time::seconds( 10 ) );
  std::cout << "Stopping service now!" << std::endl;

  // Stopping the io_service is a non-blocking call.  The threads that are
  // blocked on io_service::run() will try to return as soon as possible, but
  // they may still be in the middle of a handler.  Thus, perform a join on 
  // the server thread to guarantee a block occurs.
  io_service.stop();

  std::cout << "Waiting on server thread..." << std::endl;
  server_thread.join();
  std::cout << "Done waiting on server thread." << std::endl;

  return 0;
}

在運行時,我打開了兩個連接.這是輸出:

While running, I opened two connections. Here is the output:

Stopping service in 10 seconds...
Waiting on connection
Doing things with socket...
Done using socket, ready for another connection.
Waiting on connection
Doing things with socket...
Done using socket, ready for another connection.
Waiting on connection
Stopping service now!
Waiting on server thread...
Server thread exiting.
Done waiting on server thread.

這篇關于Boost::asio - 如何中斷被阻塞的 tcp 服務器線程?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Assertion failed (size.widthgt;0 amp;amp; size.heightgt;0)(斷言失敗(size.width0 amp;amp; size.height0))
Rotate an image in C++ without using OpenCV functions(在 C++ 中旋轉圖像而不使用 OpenCV 函數)
OpenCV: process every frame(OpenCV:處理每一幀)
Why can#39;t I open avi video in openCV?(為什么我不能在 openCV 中打開 avi 視頻?)
OpenCV unable to set up SVM Parameters(OpenCV 無法設置 SVM 參數)
Convert a single color with cvtColor(使用 cvtColor 轉換單一顏色)
主站蜘蛛池模板: 色视频成人在线观看免 | 久久久久久久一区 | 999久久久精品 | 毛片高清 | 免费av在线网站 | 欧美一区二区黄 | 91麻豆蜜桃一区二区三区 | 三级在线视频 | 国产一区二区在线看 | 久草视频在线播放 | 精品亚洲一区二区 | 免费毛片网 | 成人欧美一区二区三区黑人孕妇 | 91综合在线观看 | 亚洲a网 | 久久亚洲综合 | 成人a在线 | 国产日韩精品一区二区三区 | 欧美电影网 | 国产精品免费一区二区 | 91社区在线观看播放 | 狠狠亚洲 | 日本免费一区二区三区四区 | 国产精品自拍av | 久久国产精品一区二区三区 | 国产一区二区三区不卡av | 噜久寡妇噜噜久久寡妇 | 亚洲综合在线视频 | 永久精品| 精彩视频一区二区三区 | 在线黄色网 | 99九九视频| 亚洲精品乱码久久久久久按摩观 | 色婷婷综合网 | 久久r久久 | 特黄一级| 福利网站在线观看 | 黄视频在线网站 | 精品国产乱码久久久久久88av | 免费国产一区二区 | 亚洲欧美日韩成人在线 |