ラウンドロビンスケジューリングのアルゴリズムをPerlで実装してみた
概要
ラウンドロビン・スケジューリングは、オペレーティングシステムなどにおけるプロセスなどに関するスケジューリング規則のひとつで、単純な部類に分類される一種である。実行可能状態にあるプロセスに、順番にプロセッサを割り当てる。順番に交代する、という意の「ラウンドロビン」が名前の由来である。
原始的なラウンドロビン・スケジューリングは単純で実装が容易であり、優先度をつけたり、他のアルゴリズムと併用しなければ、リソーススタベーションも発生しない。
アルゴリズム
各タスク(またはジョブ)にはタイムスロットあるいは「クォンタム; quantum」が割り当てられる(CPU時間の割り当てであり、例えば100ミリ秒といった長さ)。job1が完了までに250msかかるとき、ラウンドロビンスケジューラは job1 が 100ms 間実行された後で中断し、他のジョブにCPU時間を割り当てる。
他のジョブがそれぞれ同じ時間(100ms)ずつ実行された後、job1 にはさらに100msのCPU時間が割り当てられ、ラウンドロビンスケジューラがその実行を中断して別のジョブにCPU時間を割り当てる。再度、他のジョブがそれぞれ同じ時間(100ms)ずつ実行された後、job1 が再度実行され、最後まで実行されることになる。
具体例
use strict; use warnings; use utf8; binmode(STDOUT, ":utf8"); &main; sub main { print "プロセス数を表す整数nとクオンタムを表す整数qを入力してください。\n"; my $input_nq = <STDIN>; chomp($input_nq); my @input_nq_arr = split(/ /, $input_nq); my $p_num = $input_nq_arr[0]; my $quantum = $input_nq_arr[1]; print "文字列name^iと整数time^iを改行区切りで入力してください。入力完了後、endと入力してください。\n"; my @input_times_arr; while (my $input_name_time = <STDIN>) { last if $input_name_time eq "end\n"; chomp($input_name_time); my $input_time = substr($input_name_time, 3); push (@input_times_arr, $input_time); } my $result_times = &queue_algorithm($p_num, $quantum, \@input_times_arr); for (my $i = 0; $i < $p_num * 2; $i = $i + 2) { my @time_name_tmp; push (@time_name_tmp, "p".$result_times->[$i], $result_times->[$i + 1]); my $result_name_time = join(' ', @time_name_tmp); print $result_name_time; } } sub queue_algorithm { my ($p_num, $quantum, $input_times_arr) = @_; $\="\n"; my @input_times_arr = @{$input_times_arr}; my @result_times; my $time = 0; for (my $i = 0; $i < $p_num; $i++) { if ($input_times_arr[0] > 0 ) { my $head_time = shift @input_times_arr; my $sub_time = $head_time - $quantum; push (@input_times_arr, $sub_time); if ($sub_time <= 0) { $time = $time + $head_time; push (@result_times, $i + 1, $time); } else { $time = $time + $quantum; } } else { my $head_time = shift @input_times_arr; push (@input_times_arr, $head_time); } if ($i == 4 && ($#result_times + 1 != $p_num * 2)) { $i = -1; } } return \@result_times; }