More Related Content
PDF
組み込み関数(intrinsic)によるSIMD入門 PDF
PDF
PDF
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜 PDF
PDF
PDF
中3女子が狂える本当に気持ちのいい constexpr PDF
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ What's hot
PDF
PDF
PDF
【Unite Tokyo 2018】誘導ミサイル完全マスター PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する PDF
PDF
20分くらいでわかった気分になれるC++20コルーチン PPTX
PDF
Python 3.9からの新定番zoneinfoを使いこなそう PDF
PDF
PDF
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ. PPT
Viewers also liked
PDF
PDF
unique_ptrにポインタ以外のものを持たせるとき PPTX
PDF
Boost.Spirit.QiとLLVM APIで遊ぼう PDF
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング - PPTX
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」 PPT
PPTX
PPTX
C++コードはいらない!UE4で作るお手軽マルチプレイネットワークゲームについて PPTX
PDF
Firefox/Thunderbirdを組織内でより良く使う PPTX
PDF
PDF
Boost study meeting opening 4 PDF
PPTX
PDF
boost::shared_ptr tutorial PDF
The Earth is not flat; but it's not round either (Geography on Boost.Geometry) DOCX
PDF
Similar to BoostAsioで可読性を求めるのは間違っているだろうか
PDF
Continuation with Boost.Context PDF
PDF
PDF
PDF
PDF
PDF
PDF
KEY
PDF
PDF
ODP
PDF
PDF
KEY
PDF
PDF
PDF
C++ Transactional Memory言語拡張の紹介 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.