各タスクがタスク間共有変数を更新するときに,タスク間の同期制御を行わないと思わぬ結果を招くことがある。
タスク間共有変数xの初期値が3のとき,タスクAが代入文x=x+xを実行し,タスクBが代入文x=x×xを実行すると,最終的なxの値が12となるのは,どの順番で実行されたときか。
ここで,各代入文はそれぞれ次の四つの部分に分けて処理される。
タスクA (x=x+x):a1 xの値を参照しeとする。
/a2 xの値を参照しfとする。
/a3 e+fを計算しgとする。
/a4 gによってxの値を更新する。
タスクB (x=x×x):b1 xの値を参照しhとする。
/b2 xの値を参照しiとする。
/b3 h×iを計算しjとする。
/b4 jによってxの値を更新する。
正答2
解説
正解は2です。
同期制御をしない2つのタスクが共有変数xを更新したときの結果を追う問題です。
各タスクは「xを参照する」「計算する」「更新する」に分かれており、途中で相手の処理が割り込むと結果が変わります。
xの初期値は3です。
【選択肢別解説】
1:× a1とa2でe=3、f=3、b1とb2でh=3、i=3となります。
a3とa4でxは6になりますが、最後にb3とb4でj=9が書き込まれ、xは9になります。
2:○ a1でe=3となった後、Bがb1〜b4を実行してh=i=3、j=9、x=9とします。
続くa2ではf=9となり、a3でg=3+9=12、a4でx=12になります。
3:× b1でh=3、a1〜a4でe=f=3、g=6、x=6となります。
その後b2でi=6、b3でj=3×6=18となり、b4でxは18になります。
4:× b1〜b3でh=i=3、j=9となり、a1〜a4でxは6に更新されます。
最後にb4で先に計算したj=9が書き込まれ、xは9になります。
【ポイント】
共有変数を複数のタスクが更新すると、実行の順序によって結果が変わります。
これを防ぐには、セマフォなどによる排他制御で、参照から更新までを他のタスクに割り込ませないようにします。