Boost-asioの2
8973 ワード
前回はBoost.を紹介しましたAsioのいくつかの特性は、相対的に抽象的で離散的で、このブログはBoost.からAsioの基礎知識は一歩一歩深く、読み終わったらBoost.Asioは全面的に理解し、把握します.Boost.AsioはC++とBoostライブラリの構文特性を採用することによって、プラットフォーム間の非同期ネットワークIO能力を提供する.だからBoostを使うAsioには基本的なネットワーク知識,C++,Boost知識が必要である.
io_サービスはBoostです.Asioのコアクラス,run()メソッドはその重要なメソッドの一つであり,その後,dispatch,post,stop,resetなどの重要なメソッドが続々と紹介される.run()メソッドの役割は、すべての作業が完了するまでプログラムをブロックし、すべてのhandlerがdispatchしたことです.あるいはstopメソッドを呼び出すとrun()メソッドもブロックされなくなります.次にrun()メソッドを説明するプログラムの例を示します.
[cpp] view plain
copy
print ?
#include
{
}
#include <boost/asio.hpp>
#include <iostream>
int main( int argc, char * argv[] )
{
boost::asio::io_service io_service;
io_service.run();
std::cout << "Do you reckon this line displays?" << std::endl;
return 0;
}
LinuxでBoostをインストール後、g++1 aを採用する.cpp -o 1a -lboost_Systemをコンパイルする(Boost.Asioはboost_systemライブラリのコンテンツを呼び出すので、リンク内容を指定する必要があります.スレッドとマルチスレッドに関連する場合は、それぞれ次のように指定します-pthread-lboost_thread-mt).実行可能ファイルを実行すると、io_に出力されていないため、出力が検出されます.サービスがタスクを追加すると、自然に終了し、ブロックされません.
通常、プログラムが自動的に終了することを望んでいません.他のタスクが処理する必要がある可能性があります.より多くの場合、プログラムがいつ終了するかを制御したいと思っています.Boost.Asioはこの点を考慮して、次の例を見ます.
[cpp] view plain
copy
print ?
#include
{
boost::asio::io_service::work work( io_service );
io_service.run();
std::cout << "Do you reckon this line displays?" << std::endl;
return 0;
#include <boost/asio.hpp>
#include <iostream>
int main( int argc, char * argv[] )
{
boost::asio::io_service io_service;
boost::asio::io_service::work work( io_service );
io_service.run();
std::cout << "Do you reckon this line displays?" << std::endl;
return 0;
}
上記の例を実行すると,プログラムは出力も終了もせず,Ctrl+Cを押すとプログラムが終了することが分かった.これは主にio_を与えたからですサービス仕事---ワーク、それは仕事を完成していない情況の時退出することはできなくて、io_service.run()はio_からサービスでworkを削除すると、プログラムが終了します.ブロックされた方法でイベント処理を実行するのが好きでない場合、Boost.Asioは、BSDソケットのような他のタスクスケジューリング方法も提供しています.pollはその1つです.poll呼び出しio_サービスのイベントループは、準備されたhandlerメソッドを実行します.pollの例(forシミュレータで実行されるループ)は、次のとおりです.
[cpp] view plain
copy
print ?
#include
{
{
std::cout << "Counter: " << x << std::endl;
}
#include <boost/asio.hpp>
#include <iostream>
int main( int argc, char * argv[] )
{
boost::asio::io_service io_service;
for( int x = 0; x < 42; ++x )
{
io_service.poll();
std::cout << "Counter: " << x << std::endl;
}
return 0;
}
プログラム出力は0から41であり、終了する.もしこの時もio_サービス仕事---resetではなくwork、結果はどうなりますか?
[cpp] view plain
copy
print ?
#include
{
boost::asio::io_service::work work( io_service );
for( int x = 0; x < 42; ++x )
io_service.poll();
}
return 0;
#include <boost/asio.hpp>
#include <iostream>
int main( int argc, char * argv[] )
{
boost::asio::io_service io_service;
boost::asio::io_service::work work( io_service );
for( int x = 0; x < 42; ++x )
{
io_service.poll();
std::cout << "Counter: " << x << std::endl;
}
return 0;
}
プログラムは0から41に出力され、終了します.これはpollメソッドが非ブロックであるためであり、現在のワークキューに準備ができているかどうかを確認するだけで実行され、すぐに戻ります.実際のプロジェクトでは、forループは一般的に何らかの形式のイベントループである.上の例でもBoost.Asioのイベント処理メカニズム、ワークオブジェクトをio_にサービスオブジェクトは作業内容を提供しますが、イベント処理handlerでio_サービスはワークを提供し、ワークは無限に生成され、pollは永遠に終了しません.したがってworkの追加はイベント処理関数の外部で行われる.
すなわち,プログラムの設定に応じてrun()メソッドとpollメソッドのどちらを用いてプログラムを実行するかを選択できる.もちろんいくつかの変異体もありますrun_one(),poll_one()は、それぞれ1つのイベント処理handlerのみが実行されることを示し、これは同時実行時にプログラムをよく制御することができる.
io_からservice.run()はio_からサービスからワークを削除するとio_service.run()はブロック状態を終了するがio_サービスにはこのようなメンバー関数はありません.この場合、resetスマートポインタによってスマートポインタが指すオブジェクトを削除することで、ワークを優雅に削除することができます.
[cpp] view plain
copy
print ?
#include
#include
int main( int argc, char * argv[] )
boost::asio::io_service io_service;
new boost::asio::io_service::work( io_service )
}
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
int main( int argc, char * argv[] )
{
boost::asio::io_service io_service;
boost::shared_ptr< boost::asio::io_service::work > work(
new boost::asio::io_service::work( io_service )
);
work.reset();
io_service.run();
std::cout << "Do you reckon this line displays?" << std::endl;
return 0;
}
io_Servicesはマルチスレッドをサポートしており、前のブログでも述べたようにio_について説明しています.サービスのスレッドスケジューリング順序.マルチスレッドの例を次に示します.
[cpp] view plain
copy
print ?
void WorkerThread()
std::cout << "Thread Start";
std::cout << "Thread Finish";
{
new boost::asio::io_service::work( io_service )
for( int x = 0; x < 4; ++x )
worker_threads.create_thread( WorkerThread );
}
void WorkerThread()
{
std::cout << "Thread Start
";
io_service.run();
std::cout << "Thread Finish
";
}
int main( int argc, char * argv[] )
{
boost::shared_ptr< boost::asio::io_service::work > work(
new boost::asio::io_service::work( io_service )
);
std::cout << "Press [return] to exit." << std::endl;
boost::thread_group worker_threads;
for( int x = 0; x < 4; ++x )
{
worker_threads.create_thread( WorkerThread );
}
std::cin.get();
io_service.stop();
worker_threads.join_all();
return 0;
}
上にstopが使われています.io_サービスは現在のワークキュー内のすべての作業を実行してから終了し、stopではなく上記のresetスマートポインタの方法を使用する必要がありますが、resetメソッドを使用する場合はio_サービスのワークキューに新しいタスクを追加すると、いつまでも停止しません.