SlideShare a Scribd company logo
Enviar búsqueda
Cargar
Effective Modern C++ study group Item39
Denunciar
Compartir
Takatoshi Kondo
Software Engineer at OGIS-RI en OGIS-RI
Seguir
•
1 recomendación
•
1,136 vistas
1
de
18
Effective Modern C++ study group Item39
•
1 recomendación
•
1,136 vistas
Denunciar
Compartir
Descargar ahora
Descargar para leer sin conexión
Software
Effective Modern C++勉強会発表資料 https://github.com/herumi/emcjp
Leer más
Takatoshi Kondo
Software Engineer at OGIS-RI en OGIS-RI
Seguir
Recomendados
続わかりやすいパターン認識8章 por
続わかりやすいパターン認識8章
Akiyoshi Hara
2.8K vistas
•
75 diapositivas
続わかりやすいパターン認識7章 por
続わかりやすいパターン認識7章
Akiyoshi Hara
685 vistas
•
24 diapositivas
Effective Modern C++勉強会#2 Item 11(,12) por
Effective Modern C++勉強会#2 Item 11(,12)
Keisuke Fukuda
1K vistas
•
10 diapositivas
effective modern c++ chapeter36 por
effective modern c++ chapeter36
Tatsuki SHIMIZU
1K vistas
•
22 diapositivas
emc++ chapter32 por
emc++ chapter32
Tatsuki SHIMIZU
1.1K vistas
•
16 diapositivas
Effective modern C++ 勉強会 #3 Item 12 por
Effective modern C++ 勉強会 #3 Item 12
Keisuke Fukuda
2.4K vistas
•
20 diapositivas
Más contenido relacionado
Destacado
Effective Modern C++ 勉強会 Item 22 por
Effective Modern C++ 勉強会 Item 22
Keisuke Fukuda
2.8K vistas
•
15 diapositivas
Effective Modern C++ 勉強会#7 Item 27 por
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
2K vistas
•
71 diapositivas
Effective Modern C++ 勉強会#3 Item 15 por
Effective Modern C++ 勉強会#3 Item 15
Mitsuru Kariya
1.3K vistas
•
59 diapositivas
Effective Modern C++ 勉強会 Item26 por
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
1.2K vistas
•
18 diapositivas
Effective Modern C++ 勉強会#6 Item25 por
Effective Modern C++ 勉強会#6 Item25
Takashi Hoshino
2K vistas
•
15 diapositivas
Effective Modern C++ 勉強会#8 Item38 por
Effective Modern C++ 勉強会#8 Item38
Takashi Hoshino
1.3K vistas
•
12 diapositivas
Destacado
(18)
Effective Modern C++ 勉強会 Item 22 por Keisuke Fukuda
Effective Modern C++ 勉強会 Item 22
Keisuke Fukuda
•
2.8K vistas
Effective Modern C++ 勉強会#7 Item 27 por Mitsuru Kariya
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
•
2K vistas
Effective Modern C++ 勉強会#3 Item 15 por Mitsuru Kariya
Effective Modern C++ 勉強会#3 Item 15
Mitsuru Kariya
•
1.3K vistas
Effective Modern C++ 勉強会 Item26 por Akihiro Nishimura
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
•
1.2K vistas
Effective Modern C++ 勉強会#6 Item25 por Takashi Hoshino
Effective Modern C++ 勉強会#6 Item25
Takashi Hoshino
•
2K vistas
Effective Modern C++ 勉強会#8 Item38 por Takashi Hoshino
Effective Modern C++ 勉強会#8 Item38
Takashi Hoshino
•
1.3K vistas
Effective modern c++ 8 por uchan_nos
Effective modern c++ 8
uchan_nos
•
1.3K vistas
Effective Modern C++ Item 24: Distinguish universal references from rvalue re... por mooopan
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
mooopan
•
1.6K vistas
Emcjp item33,34 por MITSUNARI Shigeo
Emcjp item33,34
MITSUNARI Shigeo
•
1.6K vistas
emcjp Item 42 por MITSUNARI Shigeo
emcjp Item 42
MITSUNARI Shigeo
•
1.3K vistas
Emcjp item21 por MITSUNARI Shigeo
Emcjp item21
MITSUNARI Shigeo
•
2.3K vistas
templateとautoの型推論 por MITSUNARI Shigeo
templateとautoの型推論
MITSUNARI Shigeo
•
15.2K vistas
Emcpp item31 por mitsutaka_takeda
Emcpp item31
mitsutaka_takeda
•
10.6K vistas
Emcpp item41 por mitsutaka_takeda
Emcpp item41
mitsutaka_takeda
•
10.2K vistas
Emcpp0506 por Takatoshi Kondo
Emcpp0506
Takatoshi Kondo
•
10.7K vistas
Effective Modern C++ 読書会 Item 35 por Keisuke Fukuda
Effective Modern C++ 読書会 Item 35
Keisuke Fukuda
•
11.1K vistas
Effective Modern C++勉強会#4 Item 17, 18資料 por Ryo Igarashi
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
•
11.6K vistas
Effective modern c++ 5 por uchan_nos
Effective modern c++ 5
uchan_nos
•
11.4K vistas
Más de Takatoshi Kondo
CppCon2016 report and Boost.SML por
CppCon2016 report and Boost.SML
Takatoshi Kondo
1.4K vistas
•
24 diapositivas
Pub/Sub model, msm, and asio por
Pub/Sub model, msm, and asio
Takatoshi Kondo
1.6K vistas
•
42 diapositivas
Boost sg msgpack por
Boost sg msgpack
Takatoshi Kondo
4K vistas
•
49 diapositivas
MessagePack(msgpack): Compact and Fast Serialization Library por
MessagePack(msgpack): Compact and Fast Serialization Library
Takatoshi Kondo
5.4K vistas
•
27 diapositivas
Boostsapporomsmpost 111106070819-phpapp02 por
Boostsapporomsmpost 111106070819-phpapp02
Takatoshi Kondo
662 vistas
•
95 diapositivas
Boostsapporomsmpre 111030054504-phpapp02 por
Boostsapporomsmpre 111030054504-phpapp02
Takatoshi Kondo
443 vistas
•
95 diapositivas
Más de Takatoshi Kondo
(10)
CppCon2016 report and Boost.SML por Takatoshi Kondo
CppCon2016 report and Boost.SML
Takatoshi Kondo
•
1.4K vistas
Pub/Sub model, msm, and asio por Takatoshi Kondo
Pub/Sub model, msm, and asio
Takatoshi Kondo
•
1.6K vistas
Boost sg msgpack por Takatoshi Kondo
Boost sg msgpack
Takatoshi Kondo
•
4K vistas
MessagePack(msgpack): Compact and Fast Serialization Library por Takatoshi Kondo
MessagePack(msgpack): Compact and Fast Serialization Library
Takatoshi Kondo
•
5.4K vistas
Boostsapporomsmpost 111106070819-phpapp02 por Takatoshi Kondo
Boostsapporomsmpost 111106070819-phpapp02
Takatoshi Kondo
•
662 vistas
Boostsapporomsmpre 111030054504-phpapp02 por Takatoshi Kondo
Boostsapporomsmpre 111030054504-phpapp02
Takatoshi Kondo
•
443 vistas
Unpack mechanism of the msgpack-c por Takatoshi Kondo
Unpack mechanism of the msgpack-c
Takatoshi Kondo
•
3.4K vistas
N3495 inplace realloc por Takatoshi Kondo
N3495 inplace realloc
Takatoshi Kondo
•
885 vistas
N3701 concept lite por Takatoshi Kondo
N3701 concept lite
Takatoshi Kondo
•
1.2K vistas
Aho-Corasick string matching algorithm por Takatoshi Kondo
Aho-Corasick string matching algorithm
Takatoshi Kondo
•
6.1K vistas
Effective Modern C++ study group Item39
1.
Effective Modern C++
勉強会 Item39 近藤 貴俊 2015/10/4 1
2.
今回紹介するItem • Item 39:Consider
void futures for one-shot event communication. • ワンショットイベントにvoid futureを使うことを 考えてみよう。 2015/10/4 2
3.
2015/10/4 3 std::condition_variable cv; std::mutex
m; cv.notify_one(); Item39 ... { std::unique_lock<std::mutex> lk(m); cv.wait(lk); ... } ... イベント用条件変数 cvと一緒に使うmutex cvを通してイベント通知 イベントを通知する側 イベントを受ける側 mutexをlock ここで通知を待つ イベントを受けての処理(mはlock中) イベントを受けての処理(mはlock解除されている) このコードには問題がある
4.
2015/10/4 4 std::condition_variable cv; std::mutex
m; cv.notify_one(); Item39 ... { std::unique_lock<std::mutex> lk(m); cv.wait(lk); ... } ... イベント用条件変数 cvと一緒に使うmutex cvを通してイベント通知 イベントを通知する側 イベントを受ける側 mutexをlock ここで通知を待つ イベントを受けての処理(mはlock中) イベントを受けての処理(mはlock解除されている) 問題その1 1 2 3 3 でブロックしてしまう
5.
2015/10/4 5 std::condition_variable cv; std::mutex
m; 完了しておくべき処理A cv.notify_one(); Item39 ... { std::unique_lock<std::mutex> lk(m); cv.wait(lk); 処理Aが完了していることを期待 } ... イベント用条件変数 cvと一緒に使うmutex イベントを通知する側 イベントを受ける側 ここで通知を待つ 問題その2 spurious wakeup 3 1 3 で処理Aが完了していない 2 3 Sprious wakeupとリオーダーは無関係 次ページで訂正
6.
2015/10/4 6 std::condition_variable cv; std::mutex
m; Item39 ... { std::unique_lock<std::mutex> lk(m); cv.wait(lk); } ... イベント用条件変数 cvと一緒に使うmutex イベントを通知する側 イベントを受ける側 ここで通知を待つ 問題その2 spurious wakeup 1 1 でnotifyされていないのに、ブロックが解除される。 http://d.hatena.ne.jp/yohhoy/20120326/p1 参照
7.
2015/10/4 7 Item39 ... { std::unique_lock<std::mutex> lk(m); cv.wait(lk); ... } cv.wait(lk, []{
return whether the event has occurred; }); イベントを受ける側 ラムダ式を引数に取るversionのwaitを使う 本当にイベントが発生したかどうか確認する。 発生していたらtrue このアプローチの詳細は後述 その前に
8.
2015/10/4 8 Item39 flag =
true; フラグを用いたポーリングベースのアプローチ std::atomic<bool> flag(false); atomic変数 while(!flag); イベント通知 イベントを受けての処理 ・mutex不要 ・whileループの前にフラグがセットされても問題ない ・spurious wakeupの問題も無い ・ループが回り続けるため、CPUリソースを消費する そこで、条件変数とフラグベースアプローチを組み合わせる イベントを受ける側 イベントを通知する側
9.
2015/10/4 9 Item39 ... { std::unique_lock<std::mutex> lk(m); flag
= true; } cv.notify_one(); { std::unique_lock<std::mutex> lk(m); cv.wait(lk, []{ return flag; }); ... } ... イベントを通知する側 ロックされた区間でフラグを設定 std::condition_variable cv; std::mutex m; bool flag(false); flag操作はmutexでロックされた区間で行われるので atomicでなくてよい 条件変数でイベント通知 イベントを受ける側 本当にイベントが発生したかどうか確認する。 発生していたらtrue 問題は全て解決する がコードはそこそこ複雑 この例ではflagはglobal よってキャプチャ不要
10.
2015/10/4 10 Item39 p.set_value(); std::promise<void> p;
voidのpromiseを準備 p.get_future().wait(); イベント通知 イベントを受けての処理 future/promiseを使ったアプローチ イベントを待つ
11.
2015/10/4 11 Item39 実際にスレッドを使ったコード std::promise<void> p; void
react(); void detect() { std::thread t([] { p.get_future().wait(); react(); }); ... p.set_value(); ... t.join(); } イベントを待つ側のスレッド イベントを送る側のスレッド イベントを受けての処理 tをunjoinableに Item37参照 この例ではpはglobal よってキャプチャ不要
12.
2015/10/4 12 Item39 future/promiseを使ったアプローチ std::promise<void> p; void
react(); void detect() { ThreadRAII tr( std::thread([] { p.get_future().wait(); react(); }), ThreadRAII::DtorAction::join ); ... p.set_value(); ... } Item37のThreadRAIIを使えばシンプルに?
13.
2015/10/4 13 Item39 future/promiseを使ったアプローチ std::promise<void> p; void
react(); void detect() { ThreadRAII tr( std::thread([] { p.get_future().wait(); react(); }), ThreadRAII::DtorAction::join ); ... p.set_value(); ... } Item37のThreadRAIIを使えばシンプルに? ここで例外が発生したら
14.
2015/10/4 14 Item39 future/promiseを使ったアプローチ std::promise<void> p; void
react(); void detect() { ThreadRAII tr( std::thread([] { p.get_future().wait(); react(); }), ThreadRAII::DtorAction::join ); ... p.set_value(); ... } Item37のThreadRAIIを使えばシンプルに? ここで例外が発生したら スレッドは待ったまま set_value()は呼ばれない
15.
2015/10/4 15 Item39 future/promiseを使ったアプローチ std::promise<void> p; void
react(); void detect() { ThreadRAII tr( std::thread([] { p.get_future().wait(); react(); }), ThreadRAII::DtorAction::join ); ... p.set_value(); ... } Item37のThreadRAIIを使えばシンプルに? ここで例外が発生したら スレッドは待ったまま set_value()は呼ばれない ThreadRAIIのデストラクタでjoinするため、そこでブロックし、 ThreadRAIIのデストラクタが永久に終わらない
16.
2015/10/4 16 Item39 future/promiseを使ったアプローチ std::promise<void> p; void
react(); void detect() { ThreadRAII tr( std::thread([] { p.get_future().wait(); react(); }), ThreadRAII::DtorAction::join ); { scope_exit se([] {p.set_value();}); ... } ... } struct scope_exit { scope_exit(std::function<void (void)> f) : f_(std::move(f)) {} ~scope_exit(void) { f_(); } private: std::function<void (void)> f_; }; http://melpon.org/wandbox/permlink/NdFo1yH7d9t0O2FL
17.
2015/10/4 17 Item39 future/promiseを使ったアプローチ(スレッドが複数の場合) std::promise<void> p; void
detect() { auto sf = p.get_future().share(); std::vector<std::thread> vt; for (int i = 0; i < threadsToRun; ++i) { vt.emplace_back([sf]{ sf.wait(); react(); }); } ... p.set_value(); ... for (auto& t : vt) { t.join(); } } std::shared_futureを使う 例外を検知して p.set_value()する処理は必要
18.
2015/10/4 18 Item39 • シンプルなイベント通知を条件変数を用いて実現する場合、 mutexとイベントが発生したかのチェックが必要になる。 •
この問題を回避するためにフラグを導入すれば良いが、 ポーリングベースだとブロックしない • 条件変数とフラグを組み合わせは、 通知メカニズムを堅苦しいもの(stilted)にする • std::promiseとfutureの組み合わせでこの問題を解決できる が、shared stateのためのheap memoryを必要とし、また、一 度きりの通知にしか使えない Things to Remember