O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
はたらく
スレッド
スレッド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
スレッド...
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
var a = new A();
a.Add();
var a = new A();
a.Add();
スレッドA
スレッド...
public class A {
int c = 0;
public void Add() {
c += 1;
}
}
a.Add();
スレッドA
スレッドB
複数のスレッドでオブジェクトを共有すると
アウト!
var a = new A()...
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 ...
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 ...
おしまい
Próximos SlideShares
Carregando em…5
×

はたらくスレッド

2018.09.15 Unity非同期完全に理解した勉強会でのショートセッションのスライド資料です。

  • Seja o primeiro a comentar

はたらくスレッド

  1. 1. はたらく スレッド
  2. 2. スレッドA そもそもスレッドとは スタック レジスタ スタックとレジスタはスレッド固有 スレッドB スタック レジスタ スレッドC スタック レジスタ スレッドD スタック レジスタ
  3. 3. スレッドA CPUコアひとつでマルチスレッド スタック レジスタ リソースを切り替える(コンテキストスイッチ) スレッド切り替えはOSのお仕事 スレッドB スタック レジスタ スレッドAのレジスタを退避 スレッドBのレジスタを復帰 いつ行われるか分からない
  4. 4. 問題
  5. 5. public class A { int c = 0; public void Add() { c += 1; } } この関数Addはスレッドセーフか?
  6. 6. public class A { int c = 0; public void Add() { c += 1; } } 答え この関数Addはスレッドセーフではない
  7. 7. 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 複数のスレッドで実行すると・・・
  8. 8. 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 複数のスレッドで実行すると・・・ 問題なし!あれ?
  9. 9. public class A { int c = 0; public void Add() { c += 1; } } a.Add(); スレッドA スレッドB 複数のスレッドでオブジェクトを共有すると アウト! var a = new A(); a.Add();
  10. 10. public class A { int c = 0; public void Add() { c += 1; } } 変数cがスレッド間で共有されていると アウト!
  11. 11. 0 public class A { int c = 0; public void Add() { c += 1; } } メモリ
  12. 12. 0 0 public class A { int c = 0; public void Add() { c += 1; } }
  13. 13. 0 0+1=1 public class A { int c = 0; public void Add() { c += 1; } }
  14. 14. 0 1 public class A { int c = 0; public void Add() { c += 1; } }
  15. 15. 1 1 public class A { int c = 0; public void Add() { c += 1; } }
  16. 16. 0 スレッドA スレッドB
  17. 17. 0 0
  18. 18. 0 0 0
  19. 19. 0 0+1=10+1=1
  20. 20. 1 11
  21. 21. 1 1
  22. 22. 1 期待される結果は2
  23. 23. 防ぐには・・・
  24. 24. public class A { int c = 0; Object obj = new Object(); public void Add() { lock(obj) { c += 1; } } } ロックする
  25. 25. 0 obj スレッドA スレッドB
  26. 26. 0
  27. 27. 0
  28. 28. 0
  29. 29. 0 0
  30. 30. 0 0+1=1
  31. 31. 1 1
  32. 32. 1
  33. 33. 1
  34. 34. 1
  35. 35. 1 1
  36. 36. 1 1+1=2
  37. 37. 1 2 2
  38. 38. 12
  39. 39. ロックしたくない
  40. 40. 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); } }
  41. 41. 0 0 1 int e = Interlocked.CompareExchange(ref c, d+1, d);
  42. 42. 0 0
  43. 43. 0 0 0
  44. 44. 1 0 0+1= 10+1=
  45. 45. 1 0 00 1
  46. 46. 1 0 0 0 1 CompareExchange
  47. 47. 1 0 0 1 成功
  48. 48. 1 0 0 1
  49. 49. 1 10 CompareExchange
  50. 50. 1 1 0 1 失敗
  51. 51. 1 21+1=
  52. 52. 1 21 CompareExchange
  53. 53. 2 1 成功
  54. 54. 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); } }
  55. 55. おしまい

×