3

WindowsクライアントにBoost::ASIOバージョン1.52.0を使用しています。サーバーからのすべての受信メッセージを処理するためのスレッドと、サーバーへのすべての送信メッセージを処理するための別の専用スレッドを専用にできるようにしたいと思います。現在、両方のスレッドに同じio_serviceオブジェクトを使用しています。私が心配しているのは、io_service::run()メソッドが呼び出されると、送信メッセージを処理しているスレッドが、一部の受信メッセージ呼び出しを処理するようにスケジュールされる可能性があることです。その逆も同様です。だから、私の質問-これは可能ですか?もしそうなら、2番目のio_serviceオブジェクトを使用して問題を解決しますか?スレッドごとに1つですか?これを設計するためのより良い方法はありますか?読み取りハンドラーと書き込みハンドラーの両方に複数のスレッドを使用しないようにしています。

もう1つ確認したいのは、2つ以上async_readsを同時に実行できる場合は、コードをシングルスレッド化するためにロックを使用する必要があることを読みました。同様にasync_writesan async_readが。と同時に実行できる場合にもロックを使用するasync_write必要がありますか、それともスレッドセーフである必要がありますか?

最後の質問-非同期メソッド-、、、async_connectおよびasync_readすべてasync_writeは、ワーカースレッドがio_servicerunメソッドを呼び出す前に、別のスレッドから呼び出すことができますか?

4

2 に答える 2

4

単一io_serviceの を使用する必要がありますが、呼び出すために使用する多くのスレッドは、io_service::run()が所有する非同期操作のハンドラを呼び出すこともできますio_service。これらのハンドラーが共有データ構造にアクセスする場合は、a を使用しstrandて排他的アクセスを確保する必要があります。また、最大で 1 つの書き込み操作を確保する必要があります。

この操作は、ストリームの関数への 0 回以上の呼び出しに関して実装され、構成操作async_write_someと呼ばれます。プログラムは、この操作が完了するまで、ストリームが他の書き込み操作 ( 、ストリームの 関数、または書き込みを実行するその他の合成操作など) を実行しないようにする必要があります。async_writeasync_write_some

読み取り操作_

この操作は、ストリームの関数への 0 回以上の呼び出しに関して実装され、構成操作async_read_someと呼ばれます。プログラムは、この操作が完了するまで、ストリームが他の読み取り操作 ( 、ストリームの 関数、または読み取りを実行するその他の合成操作など) を実行しないようにする必要があります。async_readasync_read_some

ソケットごとに未処理です。

すべての操作にを使用しio_service、すべてのasync_write()操作に別io_serviceのソケットを使用するasync_read()ことはできません。単一のソケットは、コンストラクターio_serviceでパラメーターとして渡されるソケットによって処理されるためです。

私の経験では、ほとんどの mult-io_service 設計は、パフォーマンスとレイテンシの要件によって決まります。HTTP Server 2の例では、 io_serviceCPU ごとにこれを調査しています。

于 2013-01-24T04:23:27.723 に答える
2

これは、操作するオブジェクト (ソケットなど) が複数ない場合に、ASIO や IOCP などの非同期ライブラリで発生する障害の 1 つです。多くの異なるエンドポイントとの間で多くのパケットを送受信する単一の UDP ソケットの一般的なケースと同様です。

このような場合、読み取り時にブロックするだけの専用スレッドを用意し、データをキューにすばやく入れ、書き込み時に専用スレッドを 1 つブロックする方が、非同期処理よりもはるかに効率的です。そうすれば、最新のハードウェアで 1 秒あたり 100K を超えるパケットを取得できるはずです。sendmmsg または recvmmsg タイプの関数を使用できる場合、オペレーティング システム コールのオーバーヘッドを回避することで、この数値をはるかに大きくすることができます。メッセージをまとめることができますが、最後に確認したところ、ASIO にはなく、独自のコードが必要になります。

サンプルアプリでは、一度にアクティブな READ または WRITE ハンドラーが 1 つしかないため、2 つのスレッドはいずれか一方のみを実行する必要があるため、ストランドの必要性を回避できます。ただし、セットアップで 2 つの専用の非非同期スレッドに移行すると、パフォーマンスが大幅に向上すると述べました。

于 2016-02-23T12:27:13.673 に答える