web-dev-qa-db-ja.com

ブーストアシオのストランドの利点は何ですか?

私が理解している限り、boost asioを勉強して、「ストランド」と呼ばれるクラスを見つけます。特定のストランドに関連付けられているio_serviceが1つしかない場合は、ストランドによってハンドルをポストします。

example(from here

boost::shared_ptr< boost::asio::io_service > io_service( 
    new boost::asio::io_service
);
boost::shared_ptr< boost::asio::io_service::work > work(
    new boost::asio::io_service::work( *io_service )
);
boost::asio::io_service::strand strand( *io_service );

boost::thread_group worker_threads;
for( int x = 0; x < 2; ++x )
{
    worker_threads.create_thread( boost::bind( &WorkerThread, io_service ) );
}

boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );

strand.post( boost::bind( &PrintNum, 1 ) );
strand.post( boost::bind( &PrintNum, 2 ) );
strand.post( boost::bind( &PrintNum, 3 ) );
strand.post( boost::bind( &PrintNum, 4 ) );
strand.post( boost::bind( &PrintNum, 5 ) );

次に、ストランドはハンドラーの実行をシリアル化しますが、これを行うことの利点は何ですか?タスクをシリアル化する必要がある場合は、単一のスレッドを作成しないのはなぜですか(例:forループでx = 1にする)?

19
StereoMatching

1つのio_serviceが数百のネットワーク接続のソケットを管理するシステムを考えてみてください。ワークロードを並列化できるようにするために、システムはio_service::runを呼び出すワーカースレッドのプールを維持します。

これで、このようなシステムのほとんどの操作を並行して実行できます。ただし、一部はシリアル化する必要があります。たとえば、同じソケットで複数の書き込み操作を同時に実行したくない場合があります。次に、ソケットごとに1つのストランドを使用して、書き込みを同期します。異なるソケットへの書き込みは同時に発生する可能性がありますが、同じソケットへの書き込みはシリアル化されます。ワーカースレッドは、同期や異なるソケットを気にする必要はありません。io_service::runが渡すものをすべて取得するだけです。

なぜ、同期の代わりにミューテックスを使用できないのでしょうか。ストランドの利点は、ストランドがすでに処理されている場合、最初にワーカースレッドがスケジュールされないことです。ミューテックスを使用すると、ワーカースレッドはコールバックを取得し、ロックの試行をブロックして、ミューテックスが使用可能になるまでスレッドが有用な作業を実行できないようにします。

34
ComicSansMS