Submit Search
Upload
BoostAsioで可読性を求めるのは間違っているだろうか
•
Download as PPTX, PDF
•
9 likes
•
14,438 views
Yuki Miyatake
Follow
Boost.Asio を読みやすくする。
Read less
Read more
Engineering
Report
Share
Report
Share
1 of 31
Download now
Recommended
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
MITSUNARI Shigeo
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
Recommended
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
MITSUNARI Shigeo
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
Fixstars Corporation
冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
C++ マルチスレッド 入門
C++ マルチスレッド 入門
京大 マイコンクラブ
中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
ELFの動的リンク
ELFの動的リンク
7shi
Constexpr 中3女子テクニック
Constexpr 中3女子テクニック
Genya Murakami
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
京大 マイコンクラブ
外部キー制約に伴うロックの小話
外部キー制約に伴うロックの小話
ichirin2501
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409
稔 小林
x86とコンテキストスイッチ
x86とコンテキストスイッチ
Masami Ichikawa
目grep入門 +解説
目grep入門 +解説
murachue
Marp Tutorial
Marp Tutorial
Rui Watanabe
TRICK 2022 Results
TRICK 2022 Results
mametter
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
Kinuko Yasuda
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
alwei
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
Genya Murakami
プログラムを高速化する話
プログラムを高速化する話
京大 マイコンクラブ
std::pin の勘所
std::pin の勘所
Hiroaki Goto
クロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
Ryosuke839
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
Shintarou Okada
More Related Content
What's hot
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
Fixstars Corporation
冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
C++ マルチスレッド 入門
C++ マルチスレッド 入門
京大 マイコンクラブ
中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
ELFの動的リンク
ELFの動的リンク
7shi
Constexpr 中3女子テクニック
Constexpr 中3女子テクニック
Genya Murakami
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
京大 マイコンクラブ
外部キー制約に伴うロックの小話
外部キー制約に伴うロックの小話
ichirin2501
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409
稔 小林
x86とコンテキストスイッチ
x86とコンテキストスイッチ
Masami Ichikawa
目grep入門 +解説
目grep入門 +解説
murachue
Marp Tutorial
Marp Tutorial
Rui Watanabe
TRICK 2022 Results
TRICK 2022 Results
mametter
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
Kinuko Yasuda
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
alwei
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
Genya Murakami
プログラムを高速化する話
プログラムを高速化する話
京大 マイコンクラブ
std::pin の勘所
std::pin の勘所
Hiroaki Goto
クロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
What's hot
(20)
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
冬のLock free祭り safe
冬のLock free祭り safe
C++ マルチスレッド 入門
C++ マルチスレッド 入門
中3女子でもわかる constexpr
中3女子でもわかる constexpr
ELFの動的リンク
ELFの動的リンク
Constexpr 中3女子テクニック
Constexpr 中3女子テクニック
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
外部キー制約に伴うロックの小話
外部キー制約に伴うロックの小話
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409
x86とコンテキストスイッチ
x86とコンテキストスイッチ
目grep入門 +解説
目grep入門 +解説
Marp Tutorial
Marp Tutorial
TRICK 2022 Results
TRICK 2022 Results
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
明日使えないすごいビット演算
明日使えないすごいビット演算
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
プログラムを高速化する話
プログラムを高速化する話
std::pin の勘所
std::pin の勘所
クロージャデザインパターン
クロージャデザインパターン
Viewers also liked
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
Ryosuke839
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
Shintarou Okada
C++がなぜ組込みに採用されにくいか
C++がなぜ組込みに採用されにくいか
Tsuyoshi Kato
Boost.Spirit.QiとLLVM APIで遊ぼう
Boost.Spirit.QiとLLVM APIで遊ぼう
nvsofts
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
Kishi Shundo
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」
Takashi Ogura
C++でHello worldを書いてみた
C++でHello worldを書いてみた
firewood
ゲーム開発経営ゲーム
ゲーム開発経営ゲーム
Yuki Miyatake
C++コードはいらない!UE4で作るお手軽マルチプレイネットワークゲームについて
C++コードはいらない!UE4で作るお手軽マルチプレイネットワークゲームについて
Masahiko Nakamura
C2C++11Level1
C2C++11Level1
Yuki Miyatake
Firefox/Thunderbirdを組織内でより良く使う
Firefox/Thunderbirdを組織内でより良く使う
Hiroshi Yuki
Boost17 cpplinq
Boost17 cpplinq
miki_hirofumi
ABC2015 Summer LT
ABC2015 Summer LT
Kensuke Onishi
Boost study meeting opening 4
Boost study meeting opening 4
Akira Takahashi
CG基礎3 メタリンク
CG基礎3 メタリンク
Tetsuro Nakamura
boost - std - C#
boost - std - C#
Tatsuya Ishikawa
boost::shared_ptr tutorial
boost::shared_ptr tutorial
NU_Pan
The Earth is not flat; but it's not round either (Geography on Boost.Geometry)
The Earth is not flat; but it's not round either (Geography on Boost.Geometry)
Vissarion Fisikopoulos
Boost勉強会 #10 ディスカッションまとめ
Boost勉強会 #10 ディスカッションまとめ
Sigureya
Glfw3,OpenGL,GUI
Glfw3,OpenGL,GUI
hira_kuni_45
Viewers also liked
(20)
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
C++がなぜ組込みに採用されにくいか
C++がなぜ組込みに採用されにくいか
Boost.Spirit.QiとLLVM APIで遊ぼう
Boost.Spirit.QiとLLVM APIで遊ぼう
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」
C++でHello worldを書いてみた
C++でHello worldを書いてみた
ゲーム開発経営ゲーム
ゲーム開発経営ゲーム
C++コードはいらない!UE4で作るお手軽マルチプレイネットワークゲームについて
C++コードはいらない!UE4で作るお手軽マルチプレイネットワークゲームについて
C2C++11Level1
C2C++11Level1
Firefox/Thunderbirdを組織内でより良く使う
Firefox/Thunderbirdを組織内でより良く使う
Boost17 cpplinq
Boost17 cpplinq
ABC2015 Summer LT
ABC2015 Summer LT
Boost study meeting opening 4
Boost study meeting opening 4
CG基礎3 メタリンク
CG基礎3 メタリンク
boost - std - C#
boost - std - C#
boost::shared_ptr tutorial
boost::shared_ptr tutorial
The Earth is not flat; but it's not round either (Geography on Boost.Geometry)
The Earth is not flat; but it's not round either (Geography on Boost.Geometry)
Boost勉強会 #10 ディスカッションまとめ
Boost勉強会 #10 ディスカッションまとめ
Glfw3,OpenGL,GUI
Glfw3,OpenGL,GUI
Similar to BoostAsioで可読性を求めるのは間違っているだろうか
SystemC Tutorial
SystemC Tutorial
kocha2012
Continuation with Boost.Context
Continuation with Boost.Context
Akira Takahashi
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
Satoshi Mimura
2008.10.18 L4u Tech Talk
2008.10.18 L4u Tech Talk
mitamex4u
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Yoshifumi Kawai
Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]
yak1ex
Effective modern-c++#9
Effective modern-c++#9
Tatsuki SHIMIZU
Boost jp9 program_options
Boost jp9 program_options
nyaocat
マルチコアを用いた画像処理
マルチコアを用いた画像処理
Norishige Fukushima
Study3 boost
Study3 boost
Kohsuke Yuasa
運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回
Shigeharu Yamaoka
競プロでGo!
競プロでGo!
鈴木 セシル
20120317 IT系勉強会 in 神戸
20120317 IT系勉強会 in 神戸
Takahiro Iwase
20130819 jjugnslt
20130819 jjugnslt
Shinya Takebayashi
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本
Kota Mizushima
Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)
Kota Mizushima
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Uehara Junji
センターSEがインスタンスの止め忘れを監視してみた
センターSEがインスタンスの止め忘れを監視してみた
弘之 石崎
Reconf 201506
Reconf 201506
Takefumi MIYOSHI
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
Hiro H.
Similar to BoostAsioで可読性を求めるのは間違っているだろうか
(20)
SystemC Tutorial
SystemC Tutorial
Continuation with Boost.Context
Continuation with Boost.Context
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
2008.10.18 L4u Tech Talk
2008.10.18 L4u Tech Talk
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]
Effective modern-c++#9
Effective modern-c++#9
Boost jp9 program_options
Boost jp9 program_options
マルチコアを用いた画像処理
マルチコアを用いた画像処理
Study3 boost
Study3 boost
運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回
競プロでGo!
競プロでGo!
20120317 IT系勉強会 in 神戸
20120317 IT系勉強会 in 神戸
20130819 jjugnslt
20130819 jjugnslt
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
センターSEがインスタンスの止め忘れを監視してみた
センターSEがインスタンスの止め忘れを監視してみた
Reconf 201506
Reconf 201506
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
BoostAsioで可読性を求めるのは間違っているだろうか
1.
Boost.Asioに可読性を求めるのは 間違っているだろうか 株式会社ムラサメ研究所 宮竹ゆき
2.
自己紹介 株式会社ムラサメ研究所(税金対策会社)主神 会社名はノリでつけました。 普通にエンジニアです。ファミリアメンバー(社 畜)募集中! ゲーム系、低レイヤー系、カーネル系 等が得意分野です C++はSTLやTemplateは今まで使ってきませんでし た 完全に食わず嫌いです constexprが読めない 大都会岡山の恥さらしです 三度の飯より TKG(卵かけごはん)が好き
3.
はじめに boost 1.57.0を前提にすすめます(1.58 でも動作確認はしたが)
Cmake clang++ でビルドしてます MacとLinuxで確認していますが、マ ルチプラットフォームなはず C++14歴1ヶ月未満の初心者です サンプルのソースは動作確認してな いので参考まで
4.
Asioを使う事になった理由 速度が要求されるサーバの案件 元のソースが bind(…); listen(…); accept(…); begin_thread(…); マルチスレッド型では同時接続数を増 やすの難しい! そうだ boost.Asioにしよう!
5.
Boost.Asioとは Asynchronous I/O。proactorパターン
シングルスレッドでI/Oを非同期で処理する 従来のmultithreadパターンだと、threadのコストが高 く、大量のクライアントを さばけない(C10K問題) カーネルにread/write命令を送り、完了時にコール バックさせるselect/epoll等のnonblocking I/Oと比較し て、user/kernelのコンテキストスイッチが少なくなる と思われる LinuxではepollでProacotr実装している模様 関数型プログラミング勉強してみたかったので、コー ルバック地獄は本望だ ラムダたん
6.
実例 boost::asio::async_read(socket_, boost::asio::buffer(data, data.length()), [this](boost::system::error_code ec,
std::size_t ){ if (!ec) { boost::asio::async_write(socket_, boost::asio::buffer(data, data.length()), [this](boost::system::error_code ec, std::size_t ){ if (!ec){ ..... }else{ //writeのエラー処理 } }); } }else{ // readのエラー処理・・ } }); はようコールバックまみれになろうぜ
7.
可読性を上げる方法 コールバックを自力でなんとかする coroutineを使う promise/futureを使う promise/futureは難しそうなので 今回はcoroutineを使う事に
8.
coroutineとは Fiber、micro thread等色々あるが、 軽量スレッドの事
疑似並列化を行う事が可能(協調的、 ノンプリエンプティブ) シングルスレッドなので同期問題が 起こりにくい Threadと違い、自分でCPUを開放す る(協調的)
9.
stackless coroutine 簡単そうだったのでこちらから
asio::coroutineを継承する 適用範囲は #include <boost/asio/yield.hpp> ~ #include <boost/asio/unyield.hpp> で囲む coroutine関数は operator()に operator()以外でも出来そうだけど調べてない coroutine部分は reenter()で囲む yield fork等をキーワードのように使え る
10.
header asio::coroutineを継承する事 class server
: boost::asio::coroutine { コールバック先の関数オブジェクト void operator()(ほげ) fork時にコンストラクタが呼ばれないので、 shared_ptr等を使うと初期化しやすい(指摘あれ ばよろしくお願いします) std::shared_ptr<tcp::acceptor> acceptor_; std::shared_ptr<tcp::socket> socket_; std::shared_ptr<std::array<char, 1024> > buffer_;
11.
operator()、reenter コルーチンが再開される場所 CPUが割り当てられた際に、登録した 関数オブジェクトハンドラが呼ばれる
reenter内の前回中断した場所から再開 される void server::operator()(boost::system::error_co de ec, std::size_t length) { if (!ec) { reenter(this){
12.
fork forkを使うと新たな疑似コンテキストを作成で きる is_parentで親子が判定出来る
新たなコンテキストは、個別のメンバを割り当 てられる(が コンストラクタはforkでは呼ばれ ない) do { socket_.reset(new tcp::socket(acceptor_->get_io_service())); yield acceptor_->async_accept(*socket_, *this); fork server(*this)(); } while (is_parent());
13.
yield 非同期処理をpostし、CPUを開放する 非同期処理完了時に、指定した関数オ ブジェクトがコールバックされる yield socket_>async_read_some(boost::asio::buff er(*buffer_),
*this); yield boost::asio::async_write(*socket_, boost::asio::buffer(*buffer_), *this);
14.
例 // coroutineを使わない例 asio::async_read(socket_, asio::buffer(buffer_), [this](boost::system::error_code
ec, std::size_t ){ asio::async_write(socket_, asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t ){ socket_.shutdown(tcp::socket::shutdown_both, ec); }); } }); // stackless_coroutineを使った例 reenter(this){ do{ yield acceptor_->async_accept(socket_,*this); fork server(*this)(); }while(is_parent()); yield socket_.async_read_some(asio::buffer(buffer_), *this); yield socket.async_write_some(asio::buffer(buffer_), *this); socket_.shutdown(tcp::socket::shutdown_both, ec); }; 可読性あがりましたよね?
15.
メリット 非常に簡単お手軽に書く事が出来る かなり軽そう(switch
caseで実装さ れてる) コールバック地獄がなくなり、一見 直列処理になり、ソースの可読性も 非常に良くなった ヘッダの追加のみで ライブラリの追 加が不要
16.
問題点 switch caseで実装されているため、 ローカル変数の扱いが制限される ローカル変数の扱い方が難しくなるた め、使用を辞めた
17.
参考 stackless coroutine
Overview http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/overvie w/core/coroutine.html AsioSample HTTP server4 http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/exampl es/cpp03_examples.html
18.
stackful coroutine 依存ライブラリ ./b2
--with-system --with-thread --with- date_time --with-regex --with-serialization asio::spawn()に、コルーチンを行いたい関数 (オブジェクト)を指定しyield_contextを取得 する Stacklessと違い、スタックコンテキストを個 別に作成するので、ローカル変数も可能 Asynchronous命令のコールバックに yield_contextを指定する 意外に簡単そう
19.
spawn spawnにより yield_contextを作成する 複数の接続を受ける場合は connection毎に
spawnする必要がある boost::asio::spawn(io_service, [&] (boost::asio::yield_context yield) { … for (;;) { tcp::socket _socket(io_service); acceptor.async_accept(_socket, yield); // C++14の汎用ラムダキャプチャ欲しい・・ asio::spawn(strand_, [_socket](asio::yield_context yield_child) { tcp::socket socket(std::move(_socket)); ….. yield_child を使う! }); } }
20.
yield 非同期関数にyield contextを渡す事で、コルーチンに 出来る acceptor.async_accept(socket_,
yield); // tcp::socketのメンバ関数でもOK socket_.async_read_some(asio::buffer(buffer_), yield); // asioのフリー関数でもOK asio::async_write(socket_, asio::buffer(buffer),yield);
21.
例外処理 yieldコンテキストを渡す際、通常は例外がthrowされ るが、operator[]を使えばエラーコード方式に出来る // 例外throw方式 socket_.async_read_some(boost::asio::buffer(buffer_), yield); //
エラーコード方式 boost::system::error_code; ec;socket_.async_read_some(boost::asio::buffer(buffer_), yield[ec]); 老害は速度の速いエラーコード方式が好き
22.
例 // coroutineを使わない例 asio::async_read(socket_, asio::buffer(buffer_), [this](boost::system::error_code
ec, std::size_t ){ asio::async_write(socket_, asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t ){ socket_.shutdown(tcp::socket::shutdown_both, ec); }); } }); // coroutineを使った例 boost::asio::spawn(strand_, [this, self](boost::asio::yield_context yield){ boost::system::error_code ec; socket_.async_read_some(asio::buffer(buffer_), yield[ec]); socket.async_write_some(asio::buffer(buffer_), yield[ec]); socket_.shutdown(tcp::socket::shutdown_both, ec); }); 可読性あがりましたよね?
23.
参考 stackful coroutine
Overview http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/overvie w/core/spawn.html Asio sample spawn http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/exampl e/cpp11/spawn/echo_server.cpp
24.
有限状態マシン(finite state machine)
通信に限らずStateパターンを使う事は 多いが、大抵はこの部分の可読性が悪 くなる 一般的にはenumでモードを設定しint型 と相互変換して使ったり、switch caseあ るいは関数ポインタ配列で実装したり State変更関数作ったり・・ 大抵は Stateがネストしたり、State変更 条件が色々あったり・・・ それらが大幅に簡略化されます
25.
Boost.MSM 有限状態マシン(finite state
machine) Boost.Statechartより速い(RTTIや virtualを使用してないっぽい) Boost::MPLを使う StateとEventを作成する transition_tableを作成し、Eventにより Stateを変更できる ガード、アクションを指定出来る
26.
Boost.MSM // 状態作成 struct start
: public boost::msm::front::state<>{}; struct end : public boost::msm::front::state<>{}; // イベント作成 struct event_goal{}; // イベントテーブル作成 struct state : public msm::front::state_machene_def<state> { struct table : mpl::vector< _row<start, event_goal, end> // goalイベントが来たら endへ遷移 > …. } state st; st.process_event(goal()); // goalイベント呼ばれたので endへ遷 移
27.
Boost.MSM Transition_tableに上限がある mpl::vectorを使っているので BOOST_MPL_LIMIT_VECTOR_SIZE を指定する
コンパイル時間がかかる pImplイデオム使おう コンパイル時にステートが決まってる必要がある 動的にステートを作らなければOK 遷移の拒否(Guard)が出来る UML2準拠らしい 遷移時のアクションを指定できる Stateでon_enter()、on_exit()をオーバーライド出来る が、それ以外に transition_tableに関数オブジェクトを登 録できる 複雑な状態遷移がある場合にはとても便利
28.
boost.Asio Tips
29.
shared_ptrキャプチャ class session{ void do_read(){ async_read(
socket_,buffer,[this](){this->hoge;}); } } 非同期なのでハンドラ実行時にthisは開放されているかもしれない ハンドラを実行しようと心の中で思ったならッ!その時スデにオブ ジェクトは終わってるんだッ! class session::enable_shared_from_this<session>{ void do_read(){ auto self(shared_from_this()); async_read( socket_,buffer,[this, self](){this->hoge;}); } } 自分のshared_ptrをキャプチャし、ハンドラ終了までオブジェクトを 終了させない
30.
timeout処理 coroutine時のtimeoutに一晩うなされた結果、下記のように行いま した asio::deadline_timer_; timer_.expires_from_now(boost::posix_time::seconds(10)); timer_.async_wait( [&socket_](const boost::system::error_code
&ec) { if (ec == boost::asio::error::operation_aborted) { cout << “cancel” << endl ; } else { socket_.cancel(); cout << “timeout” << endl ; } }); socket_.async_read_some(boost::asio::buffer(buffer_), yield[ec]); timer_.cancel(); これで正しいのかわかりませんが、現状動いています
31.
総括 マルチスレッド型は大量クライアントをさばけない(C10K) マルチスレッド型だとデータの同期処理にコストがかかる ので、非同期
I/Oを使うべき 非同期I/Oを普通に書くとコールバック地獄に陥る coroutineを使うと、直列っぽく記述出来るので可読性が上 がる stackless_coroutineはとてもコストが低そうだが、switchを 使ったマクロなため、ローカル変数等の制限が発生する stackful_coroutineは制限もなくとても便利である! ステートマシンは Boost.Statechartあるいは Boost.MSMを使 えばよい C++のジェネリックラムダが来ると更に快適になりそうだ
Download now