Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

はたらくスレッド

3,944 views

Published on

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

Published in: Technology
  • Be the first to comment

はたらくスレッド

  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. おしまい

×