Reconsidering Multithreading Design Patterns
-
Upload
atsushi-kambara -
Category
Documents
-
view
657 -
download
2
description
Transcript of Reconsidering Multithreading Design Patterns
![Page 1: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/1.jpg)
ReconsideringMultithreadingDesign Patterns
@atsukanrockAug. 2, 2014
めとべや東京 #5
![Page 2: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/2.jpg)
@atsukanrock
Loves:• C#• ASP.NET• Azure•DDD (Domain-Driven Design)
http://atsukanrock.hatenablog.com/https://github.com/atsukanrock/
![Page 3: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/3.jpg)
@atsukanrock
Loves:• C#• ASP.NET• Azure•DDD (Domain-Driven Design)
http://atsukanrock.hatenablog.com/https://github.com/atsukanrock/
http://jigokuno.com/?eid=162
![Page 4: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/4.jpg)
というわけで•文字ばっかですごめんなさい• 絵を描く時間がなかった。。。
•一緒にコード見ましょう
![Page 5: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/5.jpg)
このセッションのゴール
![Page 6: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/6.jpg)
この辺を伝えたい•NET における並列プログラミング•スレッドの排他制御•スレッドの協調•デザインパターン一覧• Producer-Consumer pattern•そして Cloud へ
![Page 7: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/7.jpg)
.NET における並列プログラミン
グ
![Page 8: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/8.jpg)
ggrks 案件• http://ufcpp.net/study/csharp/lib_parallel.html
• http://www.atmarkit.co.jp/ait/subtop/features/dotnet/app/masterasync_index.html
• http://ufcpp.wordpress.com/2012/11/12/asyncawait%E3%81%A8%E5%90%8C%E6%99%82%E5%AE%9F%E8%A1%8C%E5%88%B6%E5%BE%A1/
ググったらすばらしい記事がたくさんあります。
![Page 9: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/9.jpg)
進化してきた• Thread• ThreadPool• Asynchronous Programming Model
(APM)• Begin/EndInvoke
• Event-based Asynchronous Pattern• BackgroundWorker
• Task-based Asynchronous Pattern• Reactive Extensions (Rx)• async/await
![Page 10: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/10.jpg)
async/await 様最高•書き方が超シンプルになる• シングルスレッドに見えるのに非同期にできる
• I/O 待ちの一本道処理はこれで勝つる• ネットワーク• ファイル• データベース ( ネットワーク + ファイル )
•→Web 系のほとんどをカバー
![Page 11: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/11.jpg)
async/await 様最高•… んだけれども並列処理は不得手•書くとしたら :• Parallel.ForEach ?• Task.Run からの Task.WhenAll ?• Select(async el => …) からの Task.WhenAll ?
• “Select は非同期時代の ForEach”• http://neue.cc/2013/12/04_435.html
•とりあえず書けるけど…• デッドロック怖い• スレッド数が増えすぎて OutOfMemory になった
らどうしよう
![Page 12: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/12.jpg)
async/await 様にも弱点が…•並列処理は async/await 様でも助けてくれない•とは言え今はマルチコア CPU の時代• CPU バウンドな処理は並列でやると早くなる、実際
正しい知識とデザインパターンで戦うのです !!
![Page 13: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/13.jpg)
CPU バウンドな処理って?•画像処理•大量のテキスト処理•音声処理•ビデオ処理
![Page 14: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/14.jpg)
というわけで•ここから、 CPU バウンドな処理に役立つ並列プログラミングを学びます
![Page 15: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/15.jpg)
スレッドの排他制御
![Page 16: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/16.jpg)
lock って書いたら•スレッド排他制御できる•↓ みたいな感じで lock の後の {} 内に入れるのは 1 スレッドだけ
lock (_lockObj){ _queue.Enqueue(item); Monitor.PulseAll(_lockObj);}
![Page 17: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/17.jpg)
lock イメージ図•スレッド 1 と 2 が _lockObj のロックを取ろうとしている
_lockObj
スレッド 1
スレッド 2
メソッド 1
メソッド 2
![Page 18: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/18.jpg)
lock イメージ図•スレッド 2 がロックを取った•スレッド 1 はロックが取れなかったので待たされている
_lockObj
スレッド 1
スレッド 2
メソッド 1
メソッド 2
![Page 19: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/19.jpg)
lock イメージ図•スレッド 2 が lock の後ろの {} を抜けた•スレッド 1 にチャンスが回ってきた!
Lock Object
スレッド 1
スレッド 2
メソッド 1
メソッド 2
![Page 20: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/20.jpg)
lock イメージ図•スレッド 1 がロックを取った
Lock Object
メソッド 1
メソッド 2
![Page 21: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/21.jpg)
lock イメージ図•スレッド 1 も lock{} 抜けた
Lock Object
メソッド 1
メソッド 2
![Page 22: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/22.jpg)
スレッドの協調
![Page 23: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/23.jpg)
Wait / Pulse(All)•Monitor.Wait メソッドで、 lock{} の中で他のスレッドにロックを譲る•↓ みたいな感じlock (_lockObj){ while (_queue.Count >= _capacity) { Monitor.Wait(_lockObj); } _queue.Enqueue(item); Monitor.PulseAll(_lockObj);}
![Page 24: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/24.jpg)
Wait / Pulse(All)•Monitor.Pulse(All) メソッドで、 Wait中の他のスレッドを起こして、ロック取得競争に仲間入りさせる•実は先スライドのコードにありました↓lock (_lockObj){ while (_queue.Count >= _capacity) { Monitor.Wait(_lockObj); } _queue.Enqueue(item); Monitor.PulseAll(_lockObj);}
![Page 25: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/25.jpg)
Wait / Pulse(All)•スレッド 1 と 2 が _lockObj のロックを取り合って
_lockObj
スレッド 1
スレッド 2
メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
![Page 26: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/26.jpg)
Wait / Pulse(All)•スレッド 2 がロック取得後、 Wait に到達した•スレッド 1 は待たされている_lockObj
スレッド 1
スレッド 2
メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
![Page 27: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/27.jpg)
Wait / Pulse(All)•スレッド 2 が _lockObj の Wait セットに入ると、他スレッドにロック取得のチャンスが回ってくる
_lockObj
スレッド 1
スレッド 2
メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド2
![Page 28: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/28.jpg)
Wait / Pulse(All)•スレッド 1 がロックを取得した•スレッド 2 は Wait セットで待っている
_lockObj
スレッド 1メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド2
![Page 29: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/29.jpg)
Wait / Pulse(All)•スレッド 1 が Pulse に到達した•スレッド 2 は Wait セットで待っている
_lockObj
スレッド 1メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド2
![Page 30: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/30.jpg)
Wait / Pulse(All)•Wait セットのスレッド 2 に起きろPulse が届く
_lockObj
スレッド 1メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド2
![Page 31: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/31.jpg)
Wait / Pulse(All)•スレッド 2 がロック取得待ちに戻る•ロックはまだスレッド 1 が持っている
_lockObj
スレッド 1メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド 2
![Page 32: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/32.jpg)
Wait / Pulse(All)•スレッド 1 が lock{} を抜けた• _lockObj のロックが取得可能になった
_lockObj
スレッド 1メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド 2
![Page 33: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/33.jpg)
Wait / Pulse(All)•スレッド 2 がロックを再取得した•スレッド 2 の処理は Wait の後から再開される _lockObj
スレッド 1メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド 2
![Page 34: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/34.jpg)
Wait / Pulse(All)•スレッド 2 が lock{} を抜けた• _lockObj のロックは解放される
_lockObj
スレッド 1メソッド 1
Monitor.Pulse(_lockObj)
メソッド 2
Monitor.Wait(_lockObj)
_lockObj の Wait セット
スレッド 2
![Page 35: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/35.jpg)
Pulse と PulseAll の違い• Pulse は Wait セットにいる n 個のスレッドのうち 1 つしか起こさない• PulseAll は Wait セット内の全てのスレッドを起こす
• Pulse の方が高速と言われるが、 Pulse回数が足りていないと寝っぱなしになるリスクが
•個人的には常に PulseAll 推奨
![Page 36: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/36.jpg)
一応他にも•↓ みたいなんあるけど• Manual/AutoResetEvent• Mutex
•Wait / Pulse(All) を上手く使えば大体の協調は実現できる• Manual/AutoResetEvent は
• 重たい(らしい)• 1 プロセス内で取れる数に上限がある(あった。今は不
明)• 使いまくったら突然死
• Mutex はそもそもプロセスまたいだ協調に使うもの• 他プロセスから見えるものが軽いわけない
![Page 37: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/37.jpg)
デザインパターン一覧
![Page 38: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/38.jpg)
何かいろいろある• Single Threaded Execution• Immutable•Guarded Suspension• Balking
![Page 39: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/39.jpg)
何かいろいろある• Producer-Consumer• Read-Write Lock• Thread-Per-Message•Worker Thread
![Page 40: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/40.jpg)
何かいろいろある• Future• Two-Phase Termination• Thread-Specific Storage• Active Object
![Page 41: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/41.jpg)
説明しきれんけど•大体のパターンは普段使い or 簡単に理解できるので、個人的に最も重要かつ美しいと感じている Producer-Consumerだけに絞って解説
![Page 42: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/42.jpg)
説明しきれんけど• Single Threaded Execution• 単に lock{} のこと
• Immutable• オブジェクトの状態がコンストラクタの後では変
えられないなら、マルチスレッドで排他制御 / 協調なしで扱っても安全• お手本 : System.String クラス
•Guarded Suspension• Producer-Consumer の特殊系とみなせる
• Balking• Producer-Consumer の特殊系とみなせる
![Page 43: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/43.jpg)
説明しきれんけど• Producer-Consumer• この後どっぷり説明
• Read-Write Lock• ReaderWriterLock クラスってのが .NET 1.0 の頃
から(!) BCL にある。要は DB と同じ
• Thread-Per-Message• 普通そう組むやろ
•Worker ThreadThreadPool のことと捉えて問題ない
![Page 44: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/44.jpg)
説明しきれんけど• Future• IAsyncResult とか Task ( Awaiter )みたいなも
ん。 JavaScript で言うと promiss
• Two-Phase Termination• CancellationToken での Cancel 的な。 Cancel
要求は無理やり殺さずフラグ立てるだけ。スレッド側がフラグチェックして安全に終了する
• Thread-Specific Storage• .NET 4.0 から BCL に ThreadLocal<T> クラスが
• Active Object• いろんなパターンの組み合わせらしい
![Page 45: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/45.jpg)
Producer-Consumer pattern
![Page 46: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/46.jpg)
3種類のオブジェクト• Producer• Consumer• Channel
![Page 47: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/47.jpg)
Producer• Consumer への処理の Request を出す•例えるならわんこそば大会の調理係• 3 人で調理する• 競技者( Consumer )の目の前( Channel )が
一杯だったらちょっと待つ• 競技者の目の前が空いたら、そば( Request )を置いて調理場に戻り、次のそばを作り始める
![Page 48: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/48.jpg)
Consumer• Producer からの Request を処理する•例えるならわんこそば大会の競技者• 5 人で争う• 目の前( Channel )に置かれたそば
( Request )があればすぐに食べ始める• 目の前にそばが置かれていなければ、そばが置か
れるまで待つ(大問題 !! )
![Page 49: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/49.jpg)
Channel• Producer が Request を置く場所• Consumer が Request を取る場所•プログラム的には、 Producer やConsumer を待たせるのが最重要な役割
![Page 50: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/50.jpg)
Channel のサンプル• https://github.com/atsukanrock/MultithreadDesignPattern/blob/master/MultithreadDesignPattern/ProducerConsumer/Channel.cs•ポイント :• Add メソッドで容量( _capacity )いっぱいの場
合は Producer スレッドを待たせている( Monitor.Wait )• Take メソッドで空の場合は Consumer スレッド
を待たせている( Monitor.Wait )• Request 数の変化時に待っているスレッドを起こ
している( Monitor.PulseAll )
![Page 51: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/51.jpg)
Producer のサンプル• https://github.com/atsukanrock/MultithreadDesignPattern/blob/master/ProducerConsumer.ConsoleApp/Producer.cs• とその基底クラスたち
• 抽象化したのでちょっと分かりづらいです。。。
•ポイント :• スレッドを意識したコードがない
![Page 52: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/52.jpg)
Consumer のサンプル• https://github.com/atsukanrock/MultithreadDesignPattern/blob/master/ProducerConsumer.ConsoleApp/Consumer.cs• とその基底クラスたち
• 抽象化したので (ry
•ポイント :• スレッドを意識したコードがない !!
![Page 53: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/53.jpg)
Producer-Consumer pattern の美しい所•スレッドの協調を意識しているのがChannel だけ• Producer と Consumer はフルパワーで働いている(つもりになっている)だけ• 作っていた / 食べていたと思っていたら待ってい
た !!
•複雑さの局所化•シンプルさを保てる• KISS ( Keep It Simple, Stupid )の原則、大事
です。
![Page 54: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/54.jpg)
Producer-Consumer pattern の注意点• Producer の生産力と Consumer の消費力に差があり過ぎて、かつ Channel のCapacity が小さい場合、待ち状態のスレッドがたくさんになる
•NotifyAll でロックを取るスレッドが、Capacity 一杯 or 空状態を解消できないスレッドになる可能性が高くなる( NotifyAll のアルゴリズムがラウンドロビンなら良いんだけど、、、未調査)•NotifyAll の空打ちが頻発する
![Page 55: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/55.jpg)
Producer-Consumer pattern の注意点
•NotifyAll の空打ちが頻発する
• Producer と Consumer のスレッド数決定を慎重にすること
前スライドからの矢印
![Page 56: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/56.jpg)
Producer-Consumer pattern の発展形•典型的な(シンプルな) Channel はQueue ( FIFO )で実装される• Stack ( LIFO )にしても良いし•最後の Request だけ取って他のRequest は捨てるという形(“ LIFO-and-Clear” と名付けよう)もあり得る• 例えば Kinect プログラミングでは、センサーから
の入力情報が無慈悲に飛んでくる• ちょっと重たい画像処理をかける場合などには、
全部は処理しきれない基礎を理解していれば応用が効きます。
![Page 57: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/57.jpg)
Producer-Consumer pattern の発展形•時間があったら LIFO-and-Clear をライブコーディング(無理やな)• LIFO-and-Clear程度なら Rx を上手く使えばデフォで書けるけんども• Rx は Producer-Consumer pattern の Channel
役を立派にこなしてくれる• ソースがマルチスレッドでもシリアライズしてく
れる(らしい)し• Sample メソッドで n ミリ秒に 1 回だけデータを拾ったり、 Buffer メソッドである程度溜めてから拾ったり
• Channel自体はシンプルなクラスで済むから、自分で書いてかゆい所に手を届かせるのもヨシ• かゆうま
![Page 58: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/58.jpg)
Producer-Consumer pattern のデモ
![Page 59: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/59.jpg)
画像処理の高速化•手元のスマホで↓にアクセス !!• http://imgproc.cloudapp.net/
• 1日限定です。課金怖い
![Page 60: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/60.jpg)
画像処理の高速化•ソースは https://github.com/atsukanrock/MultithreadDesignPattern• ゴミ多いので注意されたし
• 当初、 Azure の Worker Role で処理させる目論見だった
• Emulator ではバッチリ動いた。ヒャッハー• Azure にデプローイ !!→動かぬ。ずっと Busy• 急遽方針変更。 WPF 上で全部やることに( 8/2 1:30
頃)• WPF にぎりぎり移しきった(イマココ)
![Page 61: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/61.jpg)
画像処理の高速化•時間があれば、ソースの説明• SignalR
• Publish from ASP.NET Web API• WPF client
• BlockingCollection<T>• BCL に含まれている Channel クラス• コンストラクター引数で Queue / Stack の切り替えが
可能• CompleteAdding メソッドで Producer の完了を
Channel に通知できる• Consumer は IsCompleted プロパティを見て終了判定
• WorkerBase<T>• 典型的な Consumer の基底クラス• 処理結果はイベントで返す→ Rx で受けるのが ( ・∀・ )イイ !!
![Page 62: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/62.jpg)
そして Cloud へ
![Page 63: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/63.jpg)
Producer-Consumer pattern って…• Azure の Queue と Worker に似てる•その通り• Channel はインプロセスの Queue そのもの
![Page 64: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/64.jpg)
Producer-Consumer pattern って…•Queue の場合は永続化されている
•対象外性に優れている• Producer や Consumer が急にお亡くなりになっても Queue は生きている。そう、 Queue は生きている
![Page 65: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/65.jpg)
Producer-Consumer pattern って…•Queue の場合は永続化されている
• Channel自体のパフォーマンスはもちろんインプロセスの方が良いが、 Request の追加 / 取得自体より処理の方が重たいのが普通だから、問題にならない•インプロセスではスケールアウトできないからすぐ上限が来るし
![Page 66: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/66.jpg)
Cloud 最高… ?!•データを Cloud に持っていくのでセキュリティがー•Worker をいっぱい立てたら課金がー
•エンタープライズでは意外と気軽に使えなかったりする•手軽にマルチスレッドデザインパターンを実装できると役に立つ
![Page 67: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/67.jpg)
Cloud 最高… ?!• BIG DATA (笑)の処理などプロセス境界を容易に超えられるものは Cloud へ• 節子、それ発明やない。 MapReduce や
•センサーデータ処理などプロセス境界超えられないものはマルチスレッドデザインパターンで
![Page 68: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/68.jpg)
まとめ
![Page 69: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/69.jpg)
大事なこと• async/await だけではマルチスレッドの協調が必要な並列処理は書けない•Wait / Pulse / PulseAll でおk• Immutable厨にならないように気をつけよう• 僕は昔なりました
• Producer-Consumer は超応用が効く
•Worker Role 死すべし• 嘘です勉強します。。。
![Page 70: Reconsidering Multithreading Design Patterns](https://reader036.fdocuments.in/reader036/viewer/2022062419/559220731a28ab864b8b46f0/html5/thumbnails/70.jpg)
質疑応答