1

私は RPC フレームワークに取り組んでいます。マルチ io_service 設計を使用してio_objects、IO (フロントエンド) を実行するスレッドを RPC 作業 (バックエンド) を実行するスレッドから分離したいと考えています。

フロントエンドはシングル スレッドで、バックエンドにはスレッド プールが必要です。条件変数を使用してフロントエンドとバックエンドを同期させる設計を検討していました。ただし、混同していないようです。つまり、条件変数のboost::threadサポートは利用できないようです。この件については、ここで質問があります。 boost::asioasync_wait

2 つのio_serviceio_service::post()オブジェクトを同期するために使用される可能性があることに気付きました。以下に図を添付しました。メカニズムを正しく理解しているかどうかを知りたいだけですpost。これは賢明な実装です。

rpc システムの実装

4

2 に答える 2

2

「シングルio_serviceとスレッドプールの呼び出しio_service::run()」を使用すると仮定します

また、複数のスレッドから同じソケットへの競合状態の書き込みを避けるために、フロントエンドはシングルスレッドであると想定しています。

io_service::strand(チュートリアル)を使用して同じ目標を達成できます。フロントエンドは、によって MT 同期できますio_service::strandpostsバックエンドからフロントエンドへのすべて(およびフロントエンドからフロントエンドへのハンドラーなど) は、次のようhandle_connectに でラップする必要があります。strand

バックエンド -> フロントエンド:

io_service.post(front_end.strand.wrap(
    boost::bind(&Front_end::send_response, front_end_ptr)));

またはフロントエンド -> フロントエンド:

socket.async_connect(endpoint, strand.wrap(
    boost::bind(&Front_end::handle_connect, shared_from_this(), 
    boost::asio::placeholders::error)));

また、フロントエンドからバックエンドへのすべての投稿を でラップするべきではありませんstrand

于 2011-07-22T16:43:58.490 に答える
1

バックエンドが関数のいずれかを呼び出すスレッド プールでio_service::run(), io_service::run_one(), io_service::poll(), io_service::poll_one()あり、ハンドラーが共有リソースへのアクセスを必要とする場合でも、ハンドラー自体でそれらの共有リソースを何らかの方法でロックするように注意する必要があります。

質問に投稿された限られた量の情報を考えると、上記の警告を考慮すれば、これはうまくいくと思います。

ただし、ポストする場合、必要な完了ポートを設定して待機するための測定可能なオーバーヘッドがあります。オーバーヘッドは、バックエンドの「キュー」の別の実装を使用することを避けることができます。

達成する必要があることの正確な詳細がわからない場合は、パイプラインのスレッド構築ブロック、またはより単純に同時キューのスレッド構築ブロックを調べることをお勧めします。

于 2011-07-21T17:39:30.973 に答える