2017-10-29 11 views
2

Boost ASIOの非同期読み取り機能を使用すると、同期読み取りを行う別のスレッドを使用する場合と比較して、パフォーマンス上の利点があるかどうか不思議です。ユース・ケースでは、リモート・ホストからのデータを常にリッスンする必要があります。ブーストasync_readと同期スレッドのブロッキング - パフォーマンスの違い?

非同期の場合、ioservice.run()は読み取るデータがあるまでスレッドをブロックすると信じています。同期の場合、boost :: asio:readコールは読み取るデータがあるまでブロックされます。非同期読み取りを使用する利点はありますか? iOService_run()がブロックするので、async_readを使用するときにアプリケーションがデータを待っている間にバックグラウンドで何かを必要とする場合、別のスレッドも必要になるようです。

コードは以下のようなもの(向かいのアイデアを取得しようと、コンパイルされない場合があります)次のようになります。非同期を使用して

読み取り:同期を使用して

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

void read_handler(const boost::system::error_code &ec) 
{ 
    //Read incoming message 

    //Chain the callbacks 
    socket.async_read(read_handler); 
} 

int main() 
{ 
    std::string host = "192.168.1.3"; 
    std::string port = "8888"; 
    std::cout << "Attemping connection to host " << host << " on port " << port << std::endl; 
    boost::asio::connect(tcpSocket, resolver.resolve({host, port})); 
    std::cout << "Connected" << std::endl; 

    socket.async_read(read_handler); 

    //Will block until there is data to read? 
    ioservice.run(); 
    return 0; 
} 

は別のスレッドで読み取ります

#include <thread> 

void readThread() 
{ 
    while(true) 
    { 
     //Will block until there is data to read 
     boost::asio::read(tcpSocket, boost::asio::buffer(buffer, size)); 
    } 
} 


int main() 
{ 

    std::string host = "192.168.1.3"; 
    std::string port = "8888"; 
    std::cout << "Attemping connection to host " << host << " on port " << port << std::endl; 
    boost::asio::connect(tcpSocket, resolver.resolve({host, port})); 
    std::cout << "Connected" << std::endl; 

    std::thread r{readThread}; 

    return 0; 
} 

ありがとうございます!私の経験不足をアジアとネットワークで許してください:)

+0

ネットワークはレート決定のステップです。どのAPIを使用するのかはほとんど関係ありません。 – EJP

答えて

2

これは主にスケーリングの問題です。 ASIOでは、io_serviceが中心的なI/O通知メカニズムです。 dev/epoll、I/O-Completion Ports、kqueueなどの低レベルのOS固有の通知メソッドを抽象化します。

データが入っていても何千もの同時接続を監視したいとします。接続ごとに1つのスレッドを持つブロッキング・サーバーを実装した場合は、数千のスレッドが作成され、それぞれにリソースのオーバーヘッドが発生します。あなたのシステムのCPUの数のおおよその周りにスレッドを作成し、それらのそれぞれが同時に複数の接続を待つようにすれば、よりパフォーマンスが向上します。これは、読取り操作が「バックグラウンドで実行されます」という読取り操作が非同期である場合にのみ達成され、完了したらASIOはあなたにどのような結果で完了したかに関する必要な情報を通知します。このモデルは「積極的」と呼ばれ、WinSockなどでこのように実装されています。

特にWinSockの非同期読み取りのもう1つの理由は、同期スループットよりも効率的であり、ハイスループットのサーバーでも見られます。そこでは、複数の未処理の受信動作があると、受信バッファがカーネル内にロックされ、内部受信バッファ(SO_RCVBUFなど)に強制的に戻されることなくデータを受信できるスペースが常に確保されます(UDP)を使用するか、TCPウィンドウを縮小してスループットを低下させます。

Linuxは(反応的な方法で)動作が異なります。第2の理由はカウントされません。ただし、通知引数はまだ保持されています。

関連する問題