コンピュータシステム

コンピュータにおけるタスクの排他制御って何だろう?

2020年8月13日

排他制御」、ITを勉強していると良く出てくる言葉ですよね。

今回はコンピュータ上でのタスク(仕事の単位)が共有のリソース(記憶領域)にアクセスする際に問題が発生しないための「排他制御」に関して解説します!

コンピュータ上でのタスクが使う記憶領域とは?

排他制御の説明の前に、先ずはタスクが使う記憶領域というものに関して理解しましょう。

「タスク」とはコンピュータが「実行中のプログラムである」と識別する仕事の単位です。簡単に言うと、アプリケーションやコマンドを起動した時にプログラムがメモリにロード(読み込み)されて実行できる状態になったものがタスクです。

このタスクが生成された時、OSから独立した記憶領域が割り当てられてタスクは動作します。

この記憶領域にはスタック領域やヒープ領域などあり、それぞれ「独立した記憶領域」で動作します。

この独立した領域でタスクが動作している分には誰にも迷惑掛けないので良いのですが、どのタスクからでもアクセスできる「共有の記憶領域」へ複数のタスクがアクセスする場合に問題が発生します。

1つのデータをみんなで触ってしますので、値が変になっちゃう可能性がある、ということですね。

そこで「排他制御」が必要になってくるのです。

タスクと記憶領域

排他制御が必要な理由と対策方法とは?

ある時、「タスクA」と「タスクB」があったとします。この二つのタスクがどちらからでもアクセスできる領域(共有メモリ)の値を使って処理を進めていくとします。

それぞれのタスクの動きは以下の通りです。

  • タスクが共有メモリの値を読み出す
  • 読みだした値に10を足す
  • その値を共有メモリに書き戻す

例えば共有メモリの値が50だとしたら、タスクの処理完了後の共有メモリの値は、

「50+10=60」

となりますね。

この処理(①~③)をタスクAが実施した後(に、タスクBが①~③を実施すると、共有メモリの値はタスクA実施後に「60」、タスクB実施後に「70」になりますね。

では、タスクAとタスクBがほぼ同じタイミングで実効されるとどうなるでしょうか?

タスクA、Bが同時に実行される例

  • タスクAが①の処理を実施(読み出した値は50)
  • タスクBが①の処理を実施(読み出した値は50)
  • タスクAが②の処理を実施(タスクAでの値は60)
  • タスクBが②の処理を実施(タスクBでの値は60)
  • タスクAが③の処理を実施(共有メモリの値は60)
  • タスクBが③の処理を実施(共有メモリの値は60で上書きされてしまう)

本当は共有メモリの値が70になって欲しいところが、共有メモリの値を読むタイミングによって60になってしまいます。

図に表すと以下のようになりますね。

タスクの共有メモリ同時アクセスによる問題

このようなデータが意図しない値になってしまう状態を防ぐために「排他制御」があります。

排他制御は自分が使っている領域に「ロック」を掛けて占有することで、他のタスクがその領域を読めない(使えない)状態にします。

イメージは以下の図をご参照ください。

排他制御のイメージ

まとめ

今回は排他制御に関して解説してきました。

複数のタスクを同時に処理しつつ、データの整合性を保つために排他制御を行うことは非常に重要なのですね。

最近はクラウド上で同時にファイルを編集する事も多いですが、あれも排他制御を行ってデータをリアルタイムで更新していることになりますね。

排他制御を行うことで「デッドロック」と呼ばれる処理が進まなくなってしまう問題も発生しますので、その辺もシステムとしては考慮しなければなりません。

あれをやれば、これをやる必要がある、システムの制御って難しいですね。。。

以上です!

データベースにおける排他制御やデッドロックの解説は以下記事にありますので、こちらも併せて読んでみてください。

-コンピュータシステム