SlideShare una empresa de Scribd logo
1 de 55
Descargar para leer sin conexión
はたらく
スレッド
スレッドA
そもそもスレッドとは
スタック レジスタ
スタックとレジスタはスレッド固有
スレッドB スタック レジスタ
スレッドC スタック レジスタ
スレッドD スタック レジスタ
スレッドA
CPUコアひとつでマルチスレッド
スタック レジスタ
リソースを切り替える(コンテキストスイッチ)
スレッド切り替えはOSのお仕事
スレッドB スタック レジスタ
スレッドAのレジスタを退避
スレッドBのレジスタを復帰
いつ行われるか分からない
問題
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
この関数Addはスレッドセーフか?
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
答え
この関数Addはスレッドセーフではない
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
var a = new A();
a.Add();
var a = new A();
a.Add();
スレッドA
スレッドB
複数のスレッドで実行すると・・・
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
var a = new A();
a.Add();
var a = new A();
a.Add();
スレッドA
スレッドB
複数のスレッドで実行すると・・・
問題なし!あれ?
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
a.Add();
スレッドA
スレッドB
複数のスレッドでオブジェクトを共有すると
アウト!
var a = new A();
a.Add();
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
変数cがスレッド間で共有されていると
アウト!
0
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
メモリ
0
0
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
0
0+1=1
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
0
1
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
1
1
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
0
スレッドA スレッドB
0
0
0
0 0
0
0+1=10+1=1
1
11
1
1
1
期待される結果は2
防ぐには・・・
public class A {
int c = 0;
Object obj = new Object();
public void Add() {
lock(obj) {
c += 1;
}
}
}
ロックする
0
obj
スレッドA スレッドB
0
0
0
0
0
0
0+1=1
1
1
1
1
1
1
1
1
1+1=2
1
2
2
12
ロックしたくない
public class A {
int c = 0;
public void Add() {
int d = c;
do {
int e = Interlocked.CompareExchange(ref c, d+1, d);
if (e == d) return;
else d = e;
} while (true);
}
}
0
0 1
int e = Interlocked.CompareExchange(ref c, d+1, d);
0
0
0
0
0
1
0
0+1= 10+1=
1
0
00 1
1
0
0 0 1
CompareExchange
1
0 0 1
成功
1
0 0 1
1
10
CompareExchange
1
1
0
1
失敗
1
21+1=
1
21
CompareExchange
2
1
成功
public class A {
int c = 0;
public void Add() {
int d = c;
do {
int e = Interlocked.CompareExchange(ref c, d+1, d);
if (e == d) return;
else d = e;
} while (true);
}
}
おしまい

Más contenido relacionado

Similar a はたらくスレッド

D言語会議#1
D言語会議#1D言語会議#1
D言語会議#19rnsr
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesShintarou Okada
 
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強Kiyoshi Ogawa
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
PostgreSQL10徹底解説
PostgreSQL10徹底解説PostgreSQL10徹底解説
PostgreSQL10徹底解説Masahiko Sawada
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2Masatoshi Tada
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜JustSystems Corporation
 
DTrace for biginners part(2)
DTrace for biginners part(2)DTrace for biginners part(2)
DTrace for biginners part(2)Shoji Haraguchi
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0Yuta Matsumura
 

Similar a はたらくスレッド (12)

D言語会議#1
D言語会議#1D言語会議#1
D言語会議#1
 
Java class design
Java class designJava class design
Java class design
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
 
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
Study3 boost
Study3 boostStudy3 boost
Study3 boost
 
PostgreSQL10徹底解説
PostgreSQL10徹底解説PostgreSQL10徹底解説
PostgreSQL10徹底解説
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
 
DTrace for biginners part(2)
DTrace for biginners part(2)DTrace for biginners part(2)
DTrace for biginners part(2)
 
復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0復習も兼ねて!C#6.0-7.0
復習も兼ねて!C#6.0-7.0
 
boost - std - C#
boost - std - C#boost - std - C#
boost - std - C#
 

Más de Toru Nayuki

DSPGraphを試してみた話
DSPGraphを試してみた話DSPGraphを試してみた話
DSPGraphを試してみた話Toru Nayuki
 
Project Tiny + Photon Realtime
Project Tiny +  Photon RealtimeProject Tiny +  Photon Realtime
Project Tiny + Photon RealtimeToru Nayuki
 
LTで分かる!アセンブラ
LTで分かる!アセンブラLTで分かる!アセンブラ
LTで分かる!アセンブラToru Nayuki
 
Unityから制御可能な振動・回転デバイスの比較
Unityから制御可能な振動・回転デバイスの比較Unityから制御可能な振動・回転デバイスの比較
Unityから制御可能な振動・回転デバイスの比較Toru Nayuki
 
UnityでVJする
UnityでVJするUnityでVJする
UnityでVJするToru Nayuki
 
「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜
「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜
「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜Toru Nayuki
 

Más de Toru Nayuki (7)

DSPGraphを試してみた話
DSPGraphを試してみた話DSPGraphを試してみた話
DSPGraphを試してみた話
 
Project Tiny + Photon Realtime
Project Tiny +  Photon RealtimeProject Tiny +  Photon Realtime
Project Tiny + Photon Realtime
 
LTで分かる!アセンブラ
LTで分かる!アセンブラLTで分かる!アセンブラ
LTで分かる!アセンブラ
 
Unityから制御可能な振動・回転デバイスの比較
Unityから制御可能な振動・回転デバイスの比較Unityから制御可能な振動・回転デバイスの比較
Unityから制御可能な振動・回転デバイスの比較
 
UnityでVJする
UnityでVJするUnityでVJする
UnityでVJする
 
「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜
「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜
「ずいぶんとダサいライティングを使っているのね」〜UniRxを用いた物理ベースライティング制御〜
 
Unity × PHP
Unity × PHPUnity × PHP
Unity × PHP
 

はたらくスレッド