Skip to content

Latest commit

 

History

History
70 lines (59 loc) · 2.58 KB

14.5.md

File metadata and controls

70 lines (59 loc) · 2.58 KB

全体の概要

# プロセス 処理
1 計算 受け入れ可能になったら :ready メッセージを送る
2 スケジューラ やることがあれば :fib メッセージを送る
3 計算 フィボナッチ数を計算し、結果を :answer メッセージとして送る
4 スケジューラ やることがなくなれば :shutdown メッセージを送る
5 計算 :shutdown を受信したらプロセスを終了する

計算プロセス FibSolver.fib(scheduler)

  1. :ready メッセージ送信
  2. :fib メッセージ受信
    フィボナッチ数を計算し、 :answer メッセージ送信
  3. :shutdown メッセージ受信
    プロセス終了

スケジューラプロセス Scheduler.run(num_processes, module, func, to_calculate)

  1. num_processes の数だけ以下の処理を繰り返し、num_processes 分の計算プロセスを生成
    spawn(module, func, [self])
  2. 各プロセスごとに schedule_processes を実行

Schedule.schedule_processes(processes, queue, results)

  • processes: 計算プロセスのリスト
  • queue: フィボナッチ数計算時の引数のリスト
    引数が 37 => n = 37のときのフィボナッチ数を求める
  1. :ready メッセージ受信
    • queue の要素数 > 0
      {next | tail } = queue とする
      next:fib メッセージで送信
      schedule_processes(processes, tail, results) を実行
      =>
      schedule_processes に渡す processes の要素数は変わらないが、 queue の要素数は減っていく
    • queue の要素数 = 0
      :shutdown メッセージを送信
      • process の要素数 > 0
        processes から該当するプロセスを削除し、 schedule_processes を実行
      • process の要素数 = 0
        result を「フィボナッチ数計算時の引数の降順」に並べて返す
        =>
        処理が終了
  2. :answer メッセージ受信
    受け取った結果を results に詰めて schedule_processes を実行

ガード節に length(list) > 0 を使うとすべての要素を走査してしまうので、パターンマッチを使うべき

  • [_ | _] でパターンマッチ
  • queue != []
goh@goh% elixir spawn/fib.exs
[{37, 24157817}, {37, 24157817}, {37, 24157817}, {37, 24157817}, {37, 24157817}, {37, 24157817}]

 #   time (s)
 1     6.00
 2     3.18
 3     3.06
 4     3.06
 5     3.15
 6     3.32
 7     3.00
 8     3.05
 9     3.19
10     3.20