Schi Heil と叫ぶために

hiroakiuno's blog

ミューテックス、セマフォ、条件変数、違いを整理してみよう

前回のエントリ でプロセス、スレッド、ファイバ、タスク、ジョブの違いを整理してみたところ、toshi さんから次のお題 をいただいたので、調子に乗って今回はミューテックスセマフォ、条件変数の違いについて整理してみる。なお私がグダグダしているうちに、通りすがりの猫さんが先に解答 してくれた。そちらも合わせて参照していただきたい。

まずミューテックスセマフォの違いから。一般に以下の点で違いがある。

  • ミューテックスは、ロック/非ロック の2値を管理するだけだが、セマフォは回数を管理することができる。換言すると、セマフォは個数カウンタつきのミューテックス
  • セマフォの場合はいわゆる優先度逆転現象が発生する可能性がある。一方、ミューテックスには逆転現象を回避する機構が用意されていることが多い。「優先度上限プロトコル」「優先度継承プロトコル」がそれにあたる。

さらにどこまで一般的なのか分からないが少なくともμITRON4.0仕様では、

という違いがある。なお Java の synchronized はミューテックスに近いと思う。Java は言語レベルでのマルチスレッド対応なのでわざと言葉を変えているのだろうか?Java にはそれほど精通していないので口に出すのをやめようかと思ったが、もしかすると詳しい人がこのエントリを目にするかもしれないので誤解を恐れず書いてみた。ご存知の方がいれば是非教えていただきたい。

ちなみにセマフォの語源は手旗信号だが、ミューテックスは mutual exclusion (相互排他) の略である。ミューテックスはアプリケーションの多重起動を禁止する方法として良く用いられており、そういえば私が始めてミューテックスを使ったのも Windows アプリの多重起動防止だった。

条件変数は UNIX (というかPOSIX) 用語であり、ミューテックスと一緒に使用し、スレッドをブロックして別のスレッドからのシグナルを待たせる。同じ同期の仕組みでもミューテックスセマフォが排他や数量制限として用いられる一方で、条件変数は他のタスクに実行開始を指示するトリガとして用いられる。通りすがりの猫さん が指摘しているようにいわゆるイベントに近いと思うが明確な違いがあるのか分からない。

なお、プリエンプティブなマルチタスクでは切り替えがいつ発生するかわからないので同期の仕組みが必要だが、マルチタスクでもノンプリエンプティブであれば同期の仕組みは不要となる。μITRON におけるタスクの切り替えはラウンドロビン方式ではなく優先度ベースであり、切り替えが行われるのはOSのシステムコールを呼んだタイミングであるため、ある程度タスクの遷移をコントロールすることが可能である。しかし割り込みや例外が発生した場合でもディスパッチが起こるため、またソフトウェアの変更容易性の点でも OS の同期の仕組みは必要である。

以上、できればただのグローバル変数を含めて、そもそもなぜ同期が必要なのかも分かり易く整理したかったのだが、それは次回以降にまわすことにしよう。



リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))

リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))