• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Asioを使おう!
 

Asioを使おう!

on

  • 989 views

Boost. Study Meeting #13 @Sendai slides

Boost. Study Meeting #13 @Sendai slides

Statistics

Views

Total Views
989
Views on SlideShare
989
Embed Views
0

Actions

Likes
1
Downloads
6
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Asioを使おう! Asioを使おう! Presentation Transcript

    • Boost.Asioを使おう 橋本 達明 (@chichimotsu) Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.)
    • 目次 • • • • 自己紹介とか Boost.Asioとはなにか こんなこと,できます 少し,掘り下げる Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 2
    • 本題です • Boost.Asioとは一体何なのか? – 読み方:ぶーすと・えいじお*(ay-zee-oh) – 環境依存性の高い通信処理を一手に引き受け る – v1.0 @ Boost 1.35 -> v1.10 @ Boost 1.54 *http://www.artima.com/cppsource/boost_con_07.html 中段「BoostCon, Day 3」内 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 3
    • Asioの目指すもの • リファレンスから引用 – Portability. – Scalability. – Efficiency. – Model concepts from established APIs, such as BSD sockets. – Ease to use. – Basis for further abstraction. Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 4
    • なにはともあれ • まずは,Asioを使わない場合のコードを 見てみよう – Windows 上で,localhostを通してsocket通信 – 愚直にWinAPIを叩く – clientから入力した文章が,serverで表示され る Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 5
    • まずは • client側のコード Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 6
    • Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 以下略 7
    • 続いて • server側のコード Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 8
    • Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 以下略 9
    • 動きます Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 10
    • 何が面倒か • 書き方を覚えられない – よく分からない構造体 – よく分からないメンバ変数 – よく分からないマクロ • MSDNから情報を探すのが大変 – 書き方自体はネットにいっぱい情報がある – 書き方に方言がありすぎる – そもそも公式でまとまってるページがない Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 11
    • たとえば・・・ • client 側のコードの・・・ ←コレ Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) これをMSDNで引くと・・・ 12
    • Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 13
    • (´・ω・`) Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 14
    • では • Asioを使った例を見てみませう – とりあえず動くものを作ります (例外処理とか諸々すっ飛ばしてます) – 条件は同じにする – 使うもの:基本はBoost.Asioだけ – 参考:AsioのExamples内 “Echo – blocking_tcp_echo_*.cpp” http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.html Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 15
    • えいじお. • client側 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 16
    • Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 17
    • えいじおー! • server側 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 18
    • Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 19
    • 動きます Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 20
    • 何がいいか • リファレンスが見やすい、探しやすい • 公式のサンプルがたくさん • 従来の書き方も、ちょっと楽できる書き 方も 両方できる • スレッドセーフ Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 21
    • 非常によくまとまっている 英語ですが・・・ Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 22
    • Asioでできること • 基本的には低レベルAPIの集合体 – 組み合わせればいろんなことができる – 公式のサンプルがたくさんある (私も勉強中・・・) • おまけ – シリアルポートもサポートしてます! (超便利!!) Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 23
    • では • 少し,Asioを掘り下げてみます. • 今回は,Asioのキモである io_service について,調べてきました Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 24
    • そもそもどうなっているのか Asioに含まれるオブジェクトには、 io_service のインスタンスが必要になる boost::asio::io_service io; この io_service は,OS依存の部分と繋がっている プログラマは,この io_service を通してOSのI/Oと やり取りを行う 左の図は,同期通信を行うときのダイアグラム 同期通信では、io_service を直接扱う場面は ほとんどない リファレンスより引用 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 25
    • io_serviceはどのタイミングで使う か • boostjpのコードを見てみる – “Boost逆引きリファレンス” ┗ ”ネットワーク” ┗ ”TCP” • どうやら非同期処理の際に出てくるらし い Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 26
    • 接続処理(同期Ver.) #include <iostream> #include <boost/asio.hpp> namespace asio = boost::asio; using asio::ip::tcp; int main() { asio::io_service io_service; tcp::socket socket(io_service); boost::system::error_code error; socket.connect( tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 31400), error ); } if (error) { std::cout << "connect failed : " << error.message() << std::endl; } else { std::cout << "connected" << std::endl; } Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 27
    • 接続処理(非同期Ver.) class Client { asio::io_service& io_service_; tcp::socket socket_; public: Client(asio::io_service& io_service) : io_service_(io_service), socket_(io_service) {} void connect() { socket_.async_connect( tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 31400), boost::bind(&Client::on_connect, this, asio::placeholders::error)); } }; void on_connect(const boost::system::error_code& error) { if (error) { std::cout << "connect failed : " << error.message() << std::endl; } else { std::cout << "connected" << std::endl; } } Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 28
    • 接続処理(非同期Ver.) int main() { asio::io_service io_service; Client client(io_service); client.connect(); } io_service.run(); ここまで見て、「あれ?」と思いませんか? Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 29
    • io_service.run(); • リファレンスマニュアルによると – io_serviceのイベントループをrunする – run関数は “すべての処理が終了する” “dispatchするハンドラがない” “io_serviceがstopされた” のいずれかの状態になるまでブロッキングを 行う – 続けて実行したい場合はreset関数を呼ぶ必要 有 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 30
    • 同期処理と非同期処理 • Asioにおける同期/非同期の区別 – 同期処理では、その都度処理が行われる → 動作は基本ブロッキング → 動作が完了するまで気絶状態 – 非同期処理では、処理をスタックへ登録する → ハンドラ(Handler)として登録される → dispatch関数でスタックの先頭を実行する → run(), run_one(), poll(), poll_one()で処理実行 参考:http://yutopp.hateblo.jp/entry/2011/12/15/001518 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 31
    • 同期処理 • connect 関数の例 ( TCP@Windows ) main() -> socket.connect() -> get_service().connect() { /boost/asio/basic_socket.hpp } ( TCPの場合 SocketService == stream_socket_service ) -> service_impl_.connect() { /boost/asio/stream_socket_service.hpp } ( Windowsの場合 service_impl_type == detail::win_iocp_socket_service<Protocol> ) -> sock_ops::sync_connect() { /boost/asio/detail/win_iocp_socket_service.hpp } -> sock_ops::connect() -> call_connect() -> connect() ( defined in winsock2.h ) { /boost/asio/detail/socket_ops.ipp } 注:sock_opsがOS固有のsocket関数群をラップ、socket_types.hppで切り替え Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 32
    • 非同期処理 • connect 関数の例 ( TCP@Windows ) main() -> socket.async_connect() : サービスがopenしていなければ (ここではsocket) -> io_service へハンドラを登録 (post関数) : サービスがopenしていれば -> get_service().async_connect() -> service_impl_.async_connect() -> start_connect_op() { /boost/asio/detail/impl/win_iocp_socket_service_base.ipp } -> socket_ops::connect() (Use Reactor Pattern*) *参考:http://gihyo.jp/dev/serial/01/ruby/0030 例はRubyコードですが。。。 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 33
    • 非同期処理 (cont.) • 登録されたハンドラの実行 – run(), run_one(), poll(), poll_one() でdispatch可能 run*() -> ブロッキング実行 poll*() -> ノンブロッキング実行 *_one() -> 高々1ハンドラのみ実行される Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 34
    • 非同期処理 (cont.) • run()する (TCP@Windows) main() -> io_service.run() -> impl_.run() { /boost/asio/impl/io_service.ipp } ( Windowsの場合 ipml_type == win_iocp_io_service ) -> win_iocp_io_service::run() { /boost/asio/detail/impl/win_iocp_io_service.ipp } ( この関数内でスタックからハンドラを得る ) -> do_one() { /boost/asio/detail/impl/win_iocp_io_service.ipp } ( 上記4つのdispatch用関数のどれを用いてもこれに落着する ) Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 35
    • io_serviceのその他の機能 • run()が処理中かを確認する io_service::work • 処理を直列化する ( マルチスレッド下でも正常に動作する ) io_service::strand Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 36
    • 結局io_serviceは何者なのか • 非同期処理を円滑に処理するための ハンドラスタックとその補助関数群 • 同期処理では空気 – 暗黙的に利用されている – io_serviceがサービスを保持しているので 確かに使われてはいる。。。 – サービスの取得はbasic_io_objectの仕事 Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 37
    • なぜすべてのインスタンスに必要なの か • Asioは非同期での利用が前提 – 基本的な性質は非同期を前提としているが、 「同期処理にも対応できるようにしよう」 という設計方針のように思える – 従来法との互換性を考えたら当たり前 か・・・ – 同期処理用関数はフリー関数になっている • 結論:非同期処理を使おう Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 38
    • まとめ • Asioは便利なのでみなさん使いましょう • Asioは非同期で使いましょう • シリアルポートとかもすごく簡単に使え ます • 結論:Asioすごい Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 39
    • おわり Boost. Study Meeting #13 @Sendai 2013.10.19 (Sat.) 40