Enviar búsqueda
Cargar
規格書で読むC++11のスレッド
•
21 recomendaciones
•
17,690 vistas
Kohsuke Yuasa
Seguir
2013/07/13に、Sapporo.cppとCLR/Hで合同で開催した勉強会で発表した資料。
Leer menos
Leer más
Tecnología
Denunciar
Compartir
Denunciar
Compartir
1 de 94
Descargar ahora
Descargar para leer sin conexión
Recomendados
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Kohsuke Yuasa
C++ マルチスレッド 入門
C++ マルチスレッド 入門
京大 マイコンクラブ
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
Takaaki Suzuki
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
Yuki Miyatake
イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術
Kohsuke Yuasa
中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Preferred Networks
Recomendados
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Kohsuke Yuasa
C++ マルチスレッド 入門
C++ マルチスレッド 入門
京大 マイコンクラブ
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
Takaaki Suzuki
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
Yuki Miyatake
イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術
Kohsuke Yuasa
中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Preferred Networks
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Hiro H.
最速C# 7.x
最速C# 7.x
Yamamoto Reki
非同期処理の基礎
非同期処理の基礎
信之 岩永
C#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
信之 岩永
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Yoshifumi Kawai
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
Hiro H.
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
C#で速度を極めるいろは
C#で速度を極めるいろは
Core Concept Technologies
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
慎一 古賀
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
Hajime Yanagawa
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
alwei
C# 8.0 null許容参照型
C# 8.0 null許容参照型
信之 岩永
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったか
ShunsukeNakamura17
async/await のしくみ
async/await のしくみ
信之 岩永
新しい並列for構文のご提案
新しい並列for構文のご提案
yohhoy
Deflate
Deflate
7shi
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
UnityTechnologiesJapan002
Flutterを体験してみませんか
Flutterを体験してみませんか
cch-robo
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
Preferred Networks
Más contenido relacionado
La actualidad más candente
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Hiro H.
最速C# 7.x
最速C# 7.x
Yamamoto Reki
非同期処理の基礎
非同期処理の基礎
信之 岩永
C#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
信之 岩永
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Yoshifumi Kawai
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
Hiro H.
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
C#で速度を極めるいろは
C#で速度を極めるいろは
Core Concept Technologies
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
慎一 古賀
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
Hajime Yanagawa
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
alwei
C# 8.0 null許容参照型
C# 8.0 null許容参照型
信之 岩永
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったか
ShunsukeNakamura17
async/await のしくみ
async/await のしくみ
信之 岩永
新しい並列for構文のご提案
新しい並列for構文のご提案
yohhoy
Deflate
Deflate
7shi
Glibc malloc internal
Glibc malloc internal
Motohiro KOSAKI
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
UnityTechnologiesJapan002
La actualidad más candente
(20)
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
最速C# 7.x
最速C# 7.x
非同期処理の基礎
非同期処理の基礎
C#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
STLの型の使い分け(ダイジェスト版) @ Sapporo.cpp 第7回勉強会 (2014.10.18)
templateとautoの型推論
templateとautoの型推論
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
C#で速度を極めるいろは
C#で速度を極めるいろは
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
C# 8.0 null許容参照型
C# 8.0 null許容参照型
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったか
async/await のしくみ
async/await のしくみ
新しい並列for構文のご提案
新しい並列for構文のご提案
Deflate
Deflate
Glibc malloc internal
Glibc malloc internal
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
Similar a 規格書で読むC++11のスレッド
Flutterを体験してみませんか
Flutterを体験してみませんか
cch-robo
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
Preferred Networks
エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半
Tetsuya Morimoto
Objc lambda
Objc lambda
matuura_core
Programming camp 2008, Codereading
Programming camp 2008, Codereading
Hiro Yoshioka
Apache Torqueについて
Apache Torqueについて
tako pons
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会
Koichi Sakata
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
akirahiguchi
Prosym2012
Prosym2012
MITSUNARI Shigeo
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
normalian
What is template
What is template
Akira Takahashi
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7
Tetsuya Morimoto
PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!
Shohei Okada
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門
sandai
Java class design
Java class design
t_ichioka_sg
Boost.Flyweight
Boost.Flyweight
gintenlabo
DTrace for biginners part(2)
DTrace for biginners part(2)
Shoji Haraguchi
Uart受信設計2013
Uart受信設計2013
Kiyoshi Ogawa
Vim の話
Vim の話
cohama
C#coding guideline その2_20130325
C#coding guideline その2_20130325
Yoshihisa Ozaki
Similar a 規格書で読むC++11のスレッド
(20)
Flutterを体験してみませんか
Flutterを体験してみませんか
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半
Objc lambda
Objc lambda
Programming camp 2008, Codereading
Programming camp 2008, Codereading
Apache Torqueについて
Apache Torqueについて
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
Prosym2012
Prosym2012
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
What is template
What is template
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7
PHP 2大 web フレームワークの徹底比較!
PHP 2大 web フレームワークの徹底比較!
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門
Java class design
Java class design
Boost.Flyweight
Boost.Flyweight
DTrace for biginners part(2)
DTrace for biginners part(2)
Uart受信設計2013
Uart受信設計2013
Vim の話
Vim の話
C#coding guideline その2_20130325
C#coding guideline その2_20130325
Más de Kohsuke Yuasa
オーディオ用レベルメータを作ってみよう
オーディオ用レベルメータを作ってみよう
Kohsuke Yuasa
Juceで作るオーディオアプリケーション
Juceで作るオーディオアプリケーション
Kohsuke Yuasa
最近のC++ @ Sapporo.cpp #5
最近のC++ @ Sapporo.cpp #5
Kohsuke Yuasa
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
Kohsuke Yuasa
Introduction to boost test
Introduction to boost test
Kohsuke Yuasa
C++ template-primer
C++ template-primer
Kohsuke Yuasa
Read egg oven
Read egg oven
Kohsuke Yuasa
Study3 boost
Study3 boost
Kohsuke Yuasa
Sapporocpp#2 exception-primer
Sapporocpp#2 exception-primer
Kohsuke Yuasa
Más de Kohsuke Yuasa
(9)
オーディオ用レベルメータを作ってみよう
オーディオ用レベルメータを作ってみよう
Juceで作るオーディオアプリケーション
Juceで作るオーディオアプリケーション
最近のC++ @ Sapporo.cpp #5
最近のC++ @ Sapporo.cpp #5
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
Introduction to boost test
Introduction to boost test
C++ template-primer
C++ template-primer
Read egg oven
Read egg oven
Study3 boost
Study3 boost
Sapporocpp#2 exception-primer
Sapporocpp#2 exception-primer
Último
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
博三 太田
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
FumieNakayama
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
UEHARA, Tetsutaro
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
FumieNakayama
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
akihisamiyanaga1
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
sugiuralab
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NTT DATA Technology & Innovation
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
Yuki Kikuchi
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
Hiroshi Tomioka
Último
(9)
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
規格書で読むC++11のスレッド
1.
2013/07/13 規格書で読むC++11のスレッド @hotwatermorning 1
2.
発表者自己紹介 ✤ @hotwatermorning ✤ DTMer ✤
C++ポケットリファレンス書きました!(共著) ✤ Amazonのなか見検索に対応! 2 http://www.amazon.co.jp/C-%E3%83%9D %E3%82%B1%E3%83%83%E3%83%88%E3%83%AA %E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9- %E9%AB%98%E6%A9%8B-%E6%99%B6/dp/4774157155
3.
本日のセッションを始める前に ✤ 今日のセッションはC++の規格と絡むので、手元 に規格書があると便利です。 ✤ 本日は規格書の代わりに、N3337を使用しま す。 ✤
※PDF,割とサイズが大きいので注意 3
4.
C++のスレッド 4
5.
Free Lunch Is
Over 5 ✤ タダ飯の時代は終わった ✤ 2005年 マイクロソフトの Software Architect である Herb Sutterの言葉 ✤ CPUコアのクロック数向上が頭打ちとなり、時 を待てば自ずとソフトウェアの性能が上がるとい う時代の終わり ✤ →並行プログラミングが重要に
6.
C++のスレッド ✤ 2011年に策定された新規格(通称:C++11) から、C++にマルチスレッドサポートが 導入された。 ✤ これによって、ポータブルなコードで マルチスレッドアプリケーションをかけるように なった。 6
7.
#include <iostream> #include <thread> #include
<vector> #include <functional> int main() { std::vector<int> data = GetSomeData(); int sum; std::thread th( [](std::vector<int> const &data_, int &sum_) { sum_ = 0; for(auto n : data_) { sum_ += n; } }, std::cref(data), std::ref(sum) ); th.join(); std::cout << "sum of data is : " << sum << std::endl; } C++のスレッド 7
8.
C++03との違い 8
9.
C++03までのスレッド 9 ✤ 規格で、マルチスレッドをサポートしたメモリモ デルや実行スレッドが定義されていなかった。 ✤ そのため、これまでC++でマルチスレッド処理を するためには、各プロセッサーのメモリモデルや 各処理系のスレッドの定義に依存したコードを書 く必要があった。
10.
C++11からのスレッド 10 ✤ 規格で、マルチスレッドをサポートしたメモリモ デルや実行スレッドが定義された。 ✤ マルチスレッドための言語機能やライブラリも導 入された。 ✤
標準機能のポータブルなコードでマルチスレッド が実現できるようになった。 ✤ スレッドライブラリも、最新のC++の知見をふん だんに使用しているので、洗練されている。
11.
ライブラリ 11 ✤ thread ✤ mutex/lock ✤
future/promise ✤ async/packaged_task ✤ condition_variable ✤ call_once ✤ atomic
12.
言語機能 12 ✤ static変数の初期化 ✤ thread_local変数のサポート ✤
スレッドを超えた例外の伝播(std::exception_ptr) ✤ などなど
13.
本日やる内容 13
14.
本日やる内容 14 ✤ thread ✤ mutex/lock ✤
future/promise ✤ condition_variable
15.
本日やる内容 15 ✤ thread ✤ mutex/lock ✤
future/promise ✤ condition_variable
16.
thread ✤ スレッドを扱うクラス (
30.3.1) ✤ threadクラスは新たな実行スレッドを作成したり、その スレッドの終了を待機したり、その他スレッドの状態を問 い合せる操作のメカニズムを提供します。 ✤ スレッドの作成やスレッドハンドルの管理を行う ✤ そのためプログラマが常に明示的にスレッドの作成や ハンドルの管理を意識する必要がない ✤ Not Copyable / Movable 16
17.
スレッドの作成 ✤ threadクラスのコンストラクタで、第一引数に関 数や関数オブジェクトを渡し、第二引数以降にそ の関数に適用させたい引数を渡す( 30.3.1.2/3) (
20.8.2/1) 17
18.
#include <iostream> #include <thread> void
foo(){ std::cout << "Hello" << std::endl; } int main() { // 別スレッドでfoo関数を起動 std::thread th(foo); // スレッドの終了を待機 th.join(); } スレッドの作成 18
19.
template <class F,
class ...Args> explicit thread(F&& f, Args&&... args); // というコンストラクタについて、 INVOKE ( DECAY_COPY( std::forward<F>(f) ), DECAY_COPY( std::forward<Args>(args) )... ) // が有効であるような関数や引数を渡せる コンストラクタの定義 19
20.
DECAY_COPY() ✤ 引数に渡されたオブジェクトをコピーして受け渡 す操作を表す。( 30.2.6) ✤
ただし、rvalueなオブジェクトはそのままムーブ されたり、配列は先頭要素へのポインタにするな どの変換が行われる。 ✤ 詳しくは http://d.hatena.ne.jp/yohhoy/20120306/p1 20
21.
INVOKE() ✤ 関数やメンバ関数へのポインタや関数オブジェク ト(Functor)やラムダ式など、なんらか呼び出し 可能なものを第1引数に取り、続く引数を適用し て呼び出す操作を表す。( 20.8.2) ✤
https://sites.google.com/site/cpprefjp/reference/functional/invoke ✤ http://twitter.com/Cryolite/status/216814363221303296 21
22.
// INVOKEが表す仮想的な呼び出し操作は INVOKE(f, t1,
t2, ..., tN); // 実際には以下から適切なものが呼び出される (t1.*f)(t2, ..., tN); ((*t1).*f)(t2, ..., tN); f(t1, t2, ..., tN); INVOKE() 22
23.
struct Foo {
// operator()をもつクラス // → 関数オブジェクト(別名:ファンクタ) void operator() (std::string msg) const { std::cout << "Hello " << msg << std::endl; } }; Foo foo; std::string msg = "World!"; foo("World"); // Hello World! //関数のように呼び出せる INVOKE() 23
24.
int main() {
std::string msg = "World!"; Foo foo; // 関数のように呼び出せるものは // スレッドに渡せる std::thread th(foo, msg); // Hello World! //スレッドの終了を待機 th.join(); } INVOKE() 24
25.
スレッドに参照を渡す ✤ スレッドの引数にオブジェクトの参照を渡そうと すると、DECAY_COPY()によって、コンパイル エラーとなる。 ✤ 参照型はコピーもムーブもできないため ✤
そのため、DECAY_COPY()に渡す前に参照を std::ref()やstd::cref()で包んで渡すようにする。 ✤ http://d.hatena.ne.jp/yohhoy/20120306/p1 25
26.
#include <thread> #include <iostream> #include
<functional> void add(int a, int b, int &c) { c = a + b; } int main() { int result; std::thread th1(add, 1, 2, std::ref(result)); th1.join(); std::cout << result << std::endl; } スレッドに参照を渡す 26
27.
thread ✤ スレッドを扱うクラス (
30.3.1) ✤ threadクラスは新たな実行スレッドを作成したり、その スレッドの終了を待機したり、その他スレッドの状態を問 い合せる操作のメカニズムを提供します。 ✤ スレッドの作成やスレッドハンドルの管理を行う ✤ そのためプログラマが常に明示的にスレッドの作成や ハンドルの管理を意識する必要がない ✤ Not Copyable / Movable 27
28.
Copyable Type ✤ CopyConstructible要件
と CopyAssignable要件 を満たす型 ( 17.6.3.1) ✤ データをコピーして、オブジェクト間で同じ状態 を実現できる ✤ (Copyable自体はC++規格に定義された用語で はないが、上の2つの性質をまとめてCopyable という) 28
29.
// CopyConstructible T u
= v; T(v); // CopyAssignable u = v; Copyable Type 29
30.
Movable Type ✤ MoveConstructible要件
と MoveAssignable要件 を満たす型 ( 17.6.3.1) ✤ データ(の所有権)を移動して、オブジェクト間 でデータを受け渡せる ✤ (Movable自体はC++規格に定義された用語で はないが、上の2つの性質をまとめてMovableと いう) 30
31.
// MoveConstructible T u
= SomeFunctionReturnsT(); T(SomeFunctionReturnsT()); // MoveAssignable u = SomeFunctionReturnsT(); Movable Type 31
32.
// MoveConstructible T u
= std::move(t1); T(std::move(t2)); // MoveAssignable u = std::move(t3); Movable Type 32
33.
#include <cassert> #include <thread> #include
<iostream> void foo(int a, int b) { std::cout << a << ", " << b << std::endl; } int main() { std::thread th1(foo, 1, 2); // コンパイルエラー std::thread th2 = th1; // ムーブなら問題ない std::thread th3 = std::move(th1); // ムーブ元のth1はスレッドを手放している。 assert(th1.get_id() == std::thread().get_id()); th3.join(); } スレッドの受け渡し 33
34.
thread ✤ threadクラスのデストラクタと、スレッド管理 の問題 34
35.
デストラクタとjoin/detach 35 ✤ thread::join()はスレッドの終了を待機し、 threadオブジェクトを初期化する関数 ✤ thread::detach()はスレッドの管理を手放し、 threadオブジェクトを初期化する関数
36.
デストラクタとjoin/detach 36 ✤ なんらかのスレッドを管理しているthreadオブ ジェクトが、join()もdetach()も呼び出さずにデ ストラクトされると、std::terminate()を呼び出 して、プログラムが強制終了する。 ✤ デストラクタで自動的にjoin()やdetach()を呼び出すこと にすると、プログラマの意図しないjoin()やdetach()の 呼び出しが発生し、予期しないバグを引き起こす可能性が あるため。 ✤
http://d.hatena.ne.jp/yohhoy/20120209/p1 ✤ http://d.hatena.ne.jp/yohhoy/20120211/p1 ✤ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2802.html
37.
void worker(SomeParam p) {
doSomething(); } void foo(SomeParam p) { std::thread th(worker, p); // このまま関数を抜ける // →std::terminate()で強制終了 } デストラクタとjoin/detach 37
38.
デストラクタとjoin/detach 38 ✤ このままでは、あまりに活用しにくいように思わ れるが、そもそもthreadクラスはC++で スレッドを扱うための最もプリミティブな機能な ので、このようになっている。
39.
デストラクタとjoin/detach 39 ✤ マルチスレッドや非同期処理のより高級な仕組み としてstd::asyncやstd::future/std::promiseな どが用意されている。 ✤ ただしマルチスレッドプログラミングに便利な機 能が充分に
っているとは言えない。 ✤ なのでそういうのが必要な場合はTBBや Microsoft PPLなどを使ったほうがいいかも? ✤ http://corensic.wordpress.com/2011/10/10/async-tasks-in-c11-not-quite- there-yet/ ✤ http://d.hatena.ne.jp/yohhoy/20120417/p1
40.
デストラクタとjoin/detach 40 ✤ 明示的にjoin()/detach()しなければプログラムが 強制終了する挙動は、そのままでは例外機構との 相性が悪い。 ✤ RAIIイディオムを用いて、自動でjoinを行う方法 などが以下に紹介されている。 ✤
http://akrzemi1.wordpress.com/2012/11/14/not-using-stdthread/ ✤ http://www.boost.org/doc/html/thread/ScopedThreads.html
41.
本日やる内容 41 ✤ thread ✤ mutex/lock ✤
future/promise ✤ condition_variable
42.
Mutex/Lock 42 ✤ 排他処理を実現する仕組み
43.
Mutexクラス 43 ✤ スレッド間で排他的に所有されるリソースを表す クラス (
30.4) ✤ ミューテックスオブジェクトは、データ競合に対する 保護を容易にし、execution agents間での安全なデー タ同期を可能にします。
44.
Mutexクラス 44 ✤ 標準で定義されているMutexクラスは以下の4つ ✤ std::mutex ✤
std::recursive_mutex ✤ std::timed_mutex ✤ std::recursive_timed_mutex
45.
std::mutex 45 ✤ 再帰的ロック不可なミューテックス (
30.4.1.2.1) ✤ Lockable
46.
std::recursive_mutex 46 ✤ 再帰的ロック可能なミューテックス (
30.4.1.2.2) ✤ Lockable ✤ Window APIのMutexやCritical Sectionの挙動 と同じ
47.
Lockable Type 47 ✤ 排他処理のために、標準規格のスレッドライブラ リから使用されるオブジェクトに必要とされる要 件を満たす型
( 30.2.5.3) ✤ 以下の3つのメンバ関数を持つなど ✤ m.lock() ✤ m.try_lock() ✤ m.unlock()
48.
SomeLockableType m; // 所有権を取得 m.lock(); //
所有権の取得を試行 m.try_lock(); // 所有権を手放す m.unlock(); Lockable Type 48
49.
std::timed_mutex 49 ✤ 再帰的ロック不可な 時間制限機能付きミューテックス ✤ ロック処理を制限時間まで試行する ✤
TimedLockable
50.
std::recursive_timed_mutex 50 ✤ 再帰的ロック可能な 時間制限機能付きミューテックス ✤ ロック処理を制限時間まで試行する ✤
TimedLockable
51.
TimedLockable Type 51 ✤ 排他処理のために、標準規格のスレッドライブラ リから使用されるオブジェクトに必要とされる要 件を満たす型
( 30.2.5.3) ✤ LockableTypeの性質に加え、以下のメンバ関数 を持つなど ✤ m.try_lock_for() ✤ m.try_lock_until()
52.
#include <chrono> SomeTimedLockableType m; //
指定時間だけ所有権の取得を試行 m.try_lock_for( std::chrono::seconds(3) ); // 指定時刻まで所有権の取得を試行 m.try_lock_until( std::chrono::steady_clock()::now() + std::chrono::seconds(3) ); Lockable Type 52
53.
Lockクラス 53 ✤ Lockableなオブジェクトを管理するRAIIクラス ( 30.4.2) ✤
lock とはLockableなオブジェクトの参照を保持し、ス コープを抜けるなどのデストラクト時には、その Lockableなオブジェクトをunlockするようなオブジェク トです。 execution agentはlockableオブジェクト(のロック)の 所有権を、例外安全のマナーに則って管理するための助け として、この"lock"を使用できます。
54.
Lockクラス 54 ✤ それ自身は、排他処理のための直接的な機能は持 たずに、参照として保持するMutexクラスを管理 するだけ。
55.
Lockクラス 55 ✤ 標準規格で定義されているLockクラス ✤ std::lock_guard<Mutex> ✤
std::unique_lock<Mutex>
56.
std::lock_guard<Mutex> 56 ✤ ミューテックスのシンプルな管理機構を実現する クラステンプレート ✤ テンプレート引数Mutexは、BasicLockableでな ければならない
57.
BasicLockable Type 57 ✤ 排他処理のために、標準規格のスレッドライブラ リから使用されるオブジェクトに必要とされる要 件を満たす型
( 30.2.5.3) ✤ 以下の2つのメンバ関数を持つなど ✤ m.lock() ✤ m.unlock() ✤ 前述のLockable Typeは、BasicLockable Type の性質を含んでいる
58.
SomeBasicLockableType m; // 所有権を取得 m.lock(); //
所有権を手放す m.unlock(); BasicLockable Type 58
59.
struct Worker {
//... void process() { for(int i = 0; i < 100; ++i) { //このスコープ内だけ排他処理する std::lock_guard<std::mutex> lock(mutex_); data_ = doSomething(data_); } } private: std::mutex mutex_; int data_; // ... }; std::lock_guard<Mutex> 59
60.
Lockクラス 60 ✤ 標準規格で定義されているLockクラス ✤ std::lock_guard<Mutex> ✤
std::unique_lock<Mutex>
61.
std::unique_lock<Mutex> 61 ✤ lock_guardよりも高級な処理ができるクラス ✤ Mutexオブジェクトの再割当て、ムーブ、try_lock_*によ るロックの試行
62.
Lockクラス 62 ✤ Lockクラスによって、プログラマが明示的に lock()/unlock()を対応付けて管理する必要がなく なる。 ✤ RAIIというイディオムによって、例外安全性も高 まる。 ✤
http://d.hatena.ne.jp/heisseswasser/20130508/1367988794
63.
本日やる内容 63 ✤ thread ✤ mutex/lock ✤
future/promise ✤ condition_variable
64.
future/promise 64 ✤ 並行プログラミングのPromise/Futureパターン を実現する。 ✤ あるスレッドから、同じあるいは異なるスレッド で走る関数の結果を受け取るためのコンポーネン ト。マルチスレッドプログラミングのためだけで はなく、シングルスレッドプログラムでも、非同 期処理に役立つ。(
30.6.1)
65.
future/promise 65 ✤ std::promiseクラスとstd::futureクラスの対応す るオブジェクト同士は、一つのshared stateを 共有する。(
30.6.4) ✤ データを作る側はpromiseに値を設定し、データ を受け取る側ではfutureから値を取得する
66.
void sum_async( std::vector<int>
const &data, std::promise<int> promise) { int sum = 0; for(auto n : data) { sum += n; } promise.set_value(sum); // promiseにデータをセットし } int main() { std::vector<int> data = { 1, 2, 3 }; std::promise<int> p; std::future<int> f = p.get_future(); std::thread th( sum_async, std::cref(data), std::move(p)); th.detach(); std::cout << f.get() << std::endl; // futureで受け取る } future/promise 66
67.
std::promise<R> 67 ✤ set_value(R const
&) ✤ 非同期処理の結果として値を設定 ✤ この形式の他に、Rの型によって異なるシグネチャのものが存在する。 ✤ set_exception(std::exception_ptr) ✤ 非同期処理の結果として例外を設定
68.
std::future<R> 68 ✤ get() ✤ 非同期処理の結果を取得する ✤
この形式の他に、Rの型によって戻り値やシグネチャが異なるものが存在する。 ✤ promiseで例外が設定された場合は、get()の呼び出し で、もとの例外が再送出される ✤ wait() ✤ 非同期処理の結果がpromiseに設定されるまで処理をブ ロックする(値/例外はまだ取得しない)
69.
void sum_async( std::vector<int>
const &data, std::promise<int> promise) { if(data.empty()) { std::exception_ptr pe = std::make_exception_ptr( UnexpectedDataLengthError() ); // エラーを表すときは、promiseに例外をセットする promise.set_exception(pe); } else { int sum = 0; for(auto n : data) { sum += n; } promise.set_value(sum); } } 例外の受け渡し(セット側) 69
70.
int main() {
std::vector<int> data = {}; std::promise<int> p; std::future<int> f = p.get_future(); std::thread th( sum_async, std::cref(data), std::move(p)); th.detach(); try { std::cout << f.get() << std::endl; // futureのget()で例外が再送出される } catch(UnexpectedDataLengthError &e) { std::cout << e.what() << std::endl; } } 例外の受け渡し(取得側) 70
71.
本日やる内容 71 ✤ thread ✤ mutex/lock ✤
future/promise ✤ condition_variable
72.
condition_variable 72 ✤ 条件変数という、スレッド間で同期をとる仕組み ( 30.5/1) ✤
条件変数は、ある条件が満たされた事によって他のス レッドから通知を受けたり、システム時間が設定時刻に到 達するまでスレッドをブロックするのに使用される同期プ リミティブを提供します。
73.
条件変数の動作原理 73 ✤ あるスレッドでミューテックスにロックをかけ、 条件変数にミューテックスを渡す。 ✤ 条件変数はミューテックスのロックを解放し、処 理をブロック、スレッドは待機状態になる。 ✤
別のスレッドから待機状態のスレッドに起動通知 を送る ✤ 条件変数はロックを再取得し、待機状態のスレッ ドを再開させる
74.
std::condition_variable cond; std::mutex mutex; bool
data_ready; void process_data(); void wait_for_data_to_process() { std::unique_lock<std::mutex> lock(mut); // データが準備できるまで待機する。 while(!data_ready) { cond.wait(lock); } process_data(); } condition_variable 74
75.
void retrieve_data(); void prepare_data(); void
prepare_data_for_processing() { retrieve_data(); prepare_data(); { boost::lock_guard<boost::mutex> lock(mut); data_ready=true; } // データが準備できたら待機状態のスレッドを起こす cond.notify_one(); } condition_variable 75
76.
ミューテックスの型 76 ✤ std::condition_variableではミューテックスに std::unique_lock<std::mutex>を使用する。 ✤ std::condition_variable_anyでは、排他処理 に、std::unique_lock<std::mutex>以外の別のク ラスを使用できる。
77.
hwm.task 77
78.
ここまでの機能 78 ✤ thread ✤ mutex/lock ✤
future/promise ✤ condition_variable ✤ これらを使って、タスクライブラリっぽいものを 作ってみる。
79.
hwm.task 79 ✤ Github : https://github.com/hotwatermorning/hwm.task.git
80.
hwm.task 80 ✤ Github : https://github.com/hotwatermorning/hwm.task.git ✤
git cloneして持ってきて、 SConstructに指定している Boostのパスなどを適宜書き換えて、 $> scons するとサンプルコードがビルドできる。 (※scons必要) ✤ gcc 4.8で動作確認済み。
81.
hwm.task 81 ✤ 概要 ✤ いくつかスレッドを起動させ、タスクキューにタスクが追 加されると、どれかのスレッドがそれを処理する。 ✤
起動するスレッドの数はキューの初期化時に設定できる ✤ タスクはINVOKE()のように呼び出せるものであればなん でもいい。 ✤ タスクキューへのタスクの追加はスレッドセーフ ✤ タスクキューから自動でタスクが取り出され実行され、そ の実行結果は、std::futureを通じて非同期に取得できる。
82.
hwm.task 82 ✤ task_queue.hpp ✤ タスクキュー本体。タスクを管理し、適宜どれかのスレッ ドで取り出して実行する
83.
hwm.task 83 ✤ locked_queue.hpp ✤ タスクキューの実装に使用している、コンテナ。 ✤
Producer/Consumerパターンを使用したマルチスレッド セーフなキュー
84.
hwm.task 84 ✤ task_base.hpp/task_impl.hpp ✤ タスクを表すクラス。 ✤
run()メンバ関数によって実行される。 ✤ 実際の処理を行う部分はType Erasureというイディオム によって、baseクラスに隠 される。
85.
//! タスクキューで扱うタスクを表すベースクラス namespace hwm
{ namespace detail { namespace ns_task { struct task_base { virtual ~task_base() {} virtual void run() = 0; }; }}} task_base 85
86.
//! タスクの実体クラス //! Boost.Preprocessorを用いて、10引数を取るタスクまでをサポート template<class
F BOOST_PP_ENUM_TRAILING(11, HWM_TASK_template_parameters, unused)> struct task_impl; #define BOOST_PP_LOCAL_MACRO(iteration_value) template<class F BOOST_PP_ENUM_TRAILING(iteration_value, HWM_TASK_template_parameters_specialized, unused)> struct task_impl<F BOOST_PP_ENUM_TRAILING_PARAMS(iteration_value, Arg) /*BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(10, iteration_value), HWM_TASK_default_params, unused) */> : task_base { typedef typename function_result_type<F BOOST_PP_ENUM_TRAILING_PARAMS(iteration_value, Arg)>::type result_type; typedef std::promise<result_type> promise_type; task_impl(promise_type && promise, F && f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(iteration_value, Arg, &&arg)) : promise_(boost::move(promise)) , f_(std::forward<F>(f)) BOOST_PP_ENUM_TRAILING(iteration_value, HWM_TASK_initialize_member_variables, unused) {} private: task_impl(task_impl const &) = delete; task_impl & operator=(task_impl const &) = delete; promise_type promise_; F f_; BOOST_PP_REPEAT(iteration_value, HWM_TASK_define_member_variables, unused) virtual void run() override final { try { promise_.set_value(f_(BOOST_PP_ENUM(iteration_value, HWM_TASK_apply_member_variables, unused))); } catch(...) { promise_.set_exception(std::current_exception()); } } }; /**/ task_impl 86
87.
//! タスクの実体クラス //! Boost.Preprocessorを用いて、10引数を取るタスクまでをサポート template<class
F> struct task_impl { task_imp(std::promise<F()の戻り値> &&promise, F &&f) : promise_(std::move(promise)) , f_(std::forward<F>(f)) {} std::promise<F()の戻り値> promise_; F f_; void run() override final { try { promise_.set_value(f_()); } catch(...) { promise_.set_exception(std::current_exception()); } } }; task_impl 87
88.
//! タスクの実体クラス //! Boost.Preprocessorを用いて、10引数を取るタスクまでをサポート template<class
F, class Arg0> struct task_impl { task_imp(std::promise<F()の戻り値> &&promise, F &&f, Arg0 &&arg0) : promise_(std::move(promise)) , f_(std::forward<F>(f)) , arg0_(arg0) {} std::promise<F()の戻り値> promise_; F f_; Arg0 arg0_; void run() override final { try { promise_.set_value(f_(std::forward<Arg0>(arg0_))); } catch(...) { promise_.set_exception(std::current_exception()); } } }; task_impl 88
89.
example 89
90.
namespace hwm { struct
task_queue { // タスクをキューに追加する template<class F, class... Args> std::future<F(Args)の戻り値の型> > enqueue_sync(F f, Args... args); //... }; } タスクの追加 90
91.
hwm::task_queue tq(スレッド数); std::future<int> f
= tq.enqueue_sync( [](int x1, int x2) -> int { std::cout << (x1 + x2) << std::endl; return x1 + x2; }, 10, 20 ); // タスクキューによって自動的に非同期に実行される タスクの追加 91
92.
// タスクキューに積まれた処理の結果は、 // タスク追加時に返されたfutureオブジェクトを使用して //
取得する std::cout << "calculated value : " << f.get() << std::end; 実行結果の取得 92
93.
まとめ ✤ C++11から、言語規格でスレッドがサポートさ れました。 ✤ スレッドを扱うためのライブラリも言語に追加さ れました。 ✤
これでマルチスレッドライブラリ/アプリケー ションを書くのが容易になります。 93
94.
まとめ ✤並行プログラミングを極めて タダ飯の時代を! 94
Descargar ahora