More Related Content
PDF
組み込み関数(intrinsic)によるSIMD入門 PDF
PDF
PDF
20分くらいでわかった気分になれるC++20コルーチン PDF
PDF
PDF
PPT
What's hot
PDF
中3女子が狂える本当に気持ちのいい constexpr PDF
【Unite Tokyo 2019】Understanding C# Struct All Things PPTX
PDF
PDF
PDF
プログラミングコンテストでのデータ構造 2 ~動的木編~ PDF
PDF
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~ PDF
ARM CPUにおけるSIMDを用いた高速計算入門 PDF
1076: CUDAデバッグ・プロファイリング入門 PDF
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ. PDF
PDF
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013 PPTX
PDF
20180723 PFNの研究基盤 / PFN research system infrastructure PPTX
PDF
PDF
分散学習のあれこれ~データパラレルからモデルパラレルまで~ PPTX
PPTX
Viewers also liked
PDF
PDF
PDF
unique_ptrにポインタ以外のものを持たせるとき PPTX
C++コードはいらない!UE4で作るお手軽マルチプレイネットワークゲームについて PPTX
PDF
Boost.Spirit.QiとLLVM APIで遊ぼう PPTX
PPTX
PPT
PDF
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング - PPTX
PDF
PDF
The Earth is not flat; but it's not round either (Geography on Boost.Geometry) PDF
boost::shared_ptr tutorial PPTX
DOCX
PPTX
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」 PDF
PDF
Boost study meeting opening 4 PDF
Firefox/Thunderbirdを組織内でより良く使う Similar to BoostAsioで可読性を求めるのは間違っているだろうか
PDF
PDF
PDF
PDF
PDF
Continuation with Boost.Context PDF
PDF
PDF
ODP
KEY
PDF
PDF
PDF
C++ Transactional Memory言語拡張の紹介 PDF
PDF
KEY
PDF
PDF
PDF
PDF
BoostAsioで可読性を求めるのは間違っているだろうか
- 1.
- 2.
- 3.
- 4.
- 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.
- 7.
- 8.
- 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.
- 12.
- 13.
- 14.
例
// coroutineを使わない例
asio::async_read(socket_, asio::buffer(buffer_),
[this](boost::system::error_codeec, 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.
- 16.
- 17.
参考
stackless coroutineOverview
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.
- 21.
- 22.
例
// coroutineを使わない例
asio::async_read(socket_, asio::buffer(buffer_),
[this](boost::system::error_codeec, 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 coroutineOverview
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 statemachine)
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.
- 28.
- 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.
- 31.