0

ブーストのhttp server 3 exampleのロジックを理解しようとしています。この例のリクエストは、connection.cpp 内の start() メソッドで読み取られ、次のように呼び出されます。

socket_.async_read_some(boost::asio::buffer(buffer_),
      strand_.wrap(
        boost::bind(&connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred)));

async_read_some メソッドは、すぐに戻るように文書化されていることに注意してください。次に、読み取りハンドラー ( connection::handle_read()) 内で、parse が を返す場合、async_read_some を再度呼び出すことができますboost::indeterminatesocket_.read_some(buffer)別のスレッドで作業していることを既に知っていることを考えると、これは よりもどのような利点がありますか。私が尋ねる理由は、必要に応じて read_some を呼び出すようにメッセージの解析を少し変更したいのですが、私が考えている方法は非同期読み取りでは機能しません。

また、関連する質問: 違いはありますか?

async_read_some()

boost::thread th([](){ ret = read_some(); handle_read(ret) });?

4

1 に答える 1

3

Boost.Asio のHTTP Server 3の例は、スレッド プールのサイズに依存しないようにコーディングされています。そのため、作業が別のスレッドで行われるという保証はありません。それにもかかわらず、不可知論的であることの利点は、より多くの接続でより適切にスケーリングされることです. たとえば、C10K 問題を考えてみます。同時に接続された 10000 クライアントを調べます。同期ソリューションでは、10000 クライアントでさまざまなパフォーマンスの問題やリソースの制限が発生する可能性があります。さらに、非同期の性質は、ネットワーク内の動作の変化からプログラムを隔離するのに役立ちます。たとえば、3 つのクライアントと 2 つのスレッドを持つ同期プログラムを考えてみましょう。ただし、ネットワーク上のノイズの増加により、2 つのクライアントの待ち時間が長くなります。両方のスレッドがブロックされて他のクライアントからのデータを待機している場合、3 番目のクライアントが不注意に影響を受ける可能性があります。

接続数が少なく有限で、各接続がスレッドによって処理される場合、同期サーバーと非同期サーバーのパフォーマンスの差は最小限に抑えられます。非同期プログラミングと同期プログラミングを混在させると、複雑なソリューションが複雑なソリューションになる可能性があるため、可能であれば、非同期プログラミングと同期プログラミングを混在させないようにすることをお勧めします。さらに、ほとんどの同期アルゴリズムは非同期で記述できます。

非同期操作と同期操作 (専用スレッド内で実行されている場合でも) には、2 つの大きな違いがあります。

  • スレッドセーフ。ドキュメントに記載されているように:

    一般に、個別のオブジェクトを同時に使用することは安全ですが、単一のオブジェクトを同時に使用することは安全ではありません。

    したがって、非同期操作と同期操作は、同期操作の進行中は、その操作が独自のスレッド内で呼び出されたとしても、安全に開始できません。これは半二重プロトコルでは最小限かもしれませんが、全二重プロトコルでは考慮する必要があります。

  • 操作をキャンセルする機能。この回答に記載されているように、 cancel()Boost.Asio が提供するメンバー関数を介して同期操作をキャンセルすることはできません。代わりに、アプリケーションは信号などの低レベルのメカニズムを使用する必要がある場合があります。
于 2013-04-16T04:04:16.890 に答える