Haskell による並列・並行プログラミング #9 担当: wado さん
p.123 II部 並行Haskell
並行性の必要性
複数の対話UIを必要とするアプリケーション
GHCの提供する並行性
軽量スレッド
並行プログラミングモデル
アクターモデル、共有メモリモデル、トランザクション
Haskellはどのプログラミングモデルも実現できる
並列プログラミングでは、決定性プログラミングモデルを推奨する
章立て
7~10章 スレッドと通信の基本
11章 高水準な抽象化
12章 マルチスレッドを使ったネットワークアプリケーション
13章 並行Haskellによる並列プログラミング
14章 分散プログラミング
15章 デバッグ、性能チューニング、外部コードとのインターフェース
p.125 7章 並行制御の基本:スレッドとMVar
複数のスレッドが立ち上げてエフェクトが実行されると、予測できない形で交錯する(インターリーブする)
2つのスレッドが1つのリソース(stdoutハンドル)を取り合う
途中からABABABABのような系列がでてくる→公平性のポリシーに関係する
1/50sまでは最初のスレッドが優先される(RTSの設定)
p.126 7.1 例:備忘通知
forever
threadDelay
まだ走っているスレッドが残っていても、mainが戻るとプログラムは終了する(子プロセスは消える)
p.128 7.2 通信:MVar
newEmptyEMVar :: IO (MVar a)
newMVar :: a -> IO (MVar a)
takeMVar :: MVar a -> IO a
MVarが空ならば、値が入るまで待つ(ブロック)
putMVar :: MVar a -> a -> IO()
MVarに値が入っているならばブロックする
mvar1.hs
子スレッドがMVar経由で値をメインスレッドに渡す
mvar2.hs
子スレッドがMVar経由で2つの値をメインスレッドに渡す
ブロックが親子間で交互に起きる
mvar3.hs
空のMVarを待つプログラム
永遠に値が入ってこない
ランタイムが BlockedIndefinitelyOnMVar 例外を発生させる
takeMVar でロックを獲得、putMVar でロックを開放する
外部にある状態に対するロックとしても使える
Q. 親プロセスから子プロセスにも渡せる?
A. Yes. フォークするプログラムを逆にすると良い
p.131 7.3 簡単なチャネルとしてのMVar:ログサービス
data Logger = Logger (MVar LogCommand)
data LogCommand = Message String | Stop (MVar ())
initLogger :: IO Logger
logStop :: Logger -> IO ()
p.134 7.4 共有状態としてのMVar
HaskellのMVarはロックと可変変数の組み合わせ
デッドロックなどの問題には解決法があり、10章のソフトウェアトランザクショナルメモリで議論
電話帳の例 phonebook.hs
PhoneBook = Map Name PhoneNumber を MVarで包む
電話帳の編集は takeMVar → hogehoge → putMVar する(編集してなくてもputは必要、他のスレッドが取ってこれなくなるので)
Lazy な Map を使っているとサンクが貯まる(スペースリーク)
insertのチェインができるのを防ぐために MVar を正格評価することでサンクを潰せる
一方ロック保持は長くなる
putMVar m book したあとに book を seq して NF にする
ロックを開放した直後にbookを正格評価してreturnすることでサンクを潰す
ロックの短期開放 と スペースリーク回避 の両方を意識しよう
p.136 7.5 組み立て部品としてのMVar:無制限チャネル
data Chan
newChan :: IO (Chan a)
readChan :: Chan a -> IO a
writeChan :: Chan a -> a -> IO ()
type Stream a = MVar (Item a)
チャネルはStreamの両端にアクセス可能なデータ構造
値を読み出すのは先頭、値を書き込むのは末尾
readChan でチャネルが空のときは?
takeMVarでブロックされている
他のスレッドからwriteChanされると、読み出しを続行できる
dupChan: Chanの複製
マルチキャストチャネル
readMVar を工夫しないとデッドロックに陥る
wadoさんのスライドを見るとわかりやすい
担当: wado さん
p.136 7.5 組み立て部品としてのMVar:無制限チャネル 続き
unGetChan
p.141 7.6 公平性
担当: lotz さん
p.143 8章 入出力の重ね合わせ