みんな腹の底では良く分かってなくて、曖昧なままに放置されている事柄が多数あります。たいていそういう話は、厳密に分かっていなくても誰も困らないし、実害もないので放置されるわけです。
聞くは一瞬の恥、聞かぬは一生の恥なんですがねぇ。
いまどきは、googleさんがいますので、ググれば恥にもならないわけです。それでも、ネット上の情報はアテにならないという、それ自身が迷信であるという逆説的なデッドロックで思考停止になっている人のいかに多いことか。
さて、スレッドやプロセス、μITRONのようなRTOSならタスクでもいいわけですが、そういうコンテキストがどういう条件で切り替わるかご存知ですか?つまりコンテキストスイッチの条件です。
現在実行中のスレッドよりも優先度の高いスレッド(コンテキスト)が実行可能状態になったら
ここまではどこへ行ってもコンセンサスがあります。実行可能状態というのは、セマフォスピンロックやなどで待っていない状態ですね。つまり暗黙的に上記の条件は、以下のように解釈されます。
- 優先度の高いスレッドAが実行中にセマフォで待ちになった。→実行中でなくなる
- 次に優先度の高いスレッドBが実行中になる。
- しばらくして、セマフォが解放されてスレッドAが実行中になる。
ここまでもご同意いただけると思います。問題は、3番目の、コンテキストスイッチが、具体的にいつ起こるかなのです。
ある人は、スレッドBがシステムコール(OSが用意した関数群)を呼び出して、カーネルに入り込まない限り、コンテキストスイッチは生じないと主張します。つまり、システムコールをまったく呼ばない実装になっているとコンテキストスイッチのタイミングがどんどん遅れると言うのです。(マジデスカ)
別の人は、カーネルが定期的にセマフォの状態を更新するので、そのタイミングでコンテキストスイッチが発生すると主張します。そんな話どこで聞いてきたのよ。
実は、TSSなしの単純なRTOSなら前者はかなり正解に近いです。しかしTSSなしでも割り込みはあります。割り込みハンドラ内でセマフォを解放する、というのはセマフォの典型的なサンプルです。ドライバは、セマフォを待ち、割り込み発生ごとに1回処理を進めます。ちょっと脱線しましたが、OSの割り込み処理はコンテキストスイッチの起こりうるタイミングです。
TSSはタイマー割り込みなので、同じことです。
というわけでコンテキストスイッチのタイミングは以下のようになります
- システムコール呼び出し時
- 割り込み発生時(ソフトウェア割り込み含む)
Linuxなどでは、システムコールから戻るとき、割り込みハンドラ終了時の処理でコンテキストスイッチを実行するようです。詳細は調べてください。
割り込みって何だっけ?という状態では、当然コンテキストスイッチについて理解できたことにはなりません。読んでると眠くなる情報処理の教科書には、どんなに薄っぺらくても割り込みのことが書いてあります。あれは無駄ではないのです。

組み込みソフトウェアの設計&検証―割り込み動作からRTOSを使った設計、ツールによる動作検証まで (TECH 1「Embedded Software」)
- 作者: 藤倉俊幸
- 出版社/メーカー: CQ出版
- 発売日: 2006/09
- メディア: 単行本
- 購入: 1人 クリック: 15回
- この商品を含むブログ (5件) を見る
(2008.02.16追記)
Windows3.1系では、明示的にyieldしてCPUを明け渡さないとスケジューラが走らないというツッコミがありました。なるほどプリエンプションがないならそうでしょうが、このエントリではコンテキストスイッチが知らない間に発生することとそれが発生する条件を説明しています。
明示的に指定しないといけないOS、もしかしたらしょうもないμITRONの実装もそうなっているかもしれませんが、において明示的にコンテキストスイッチを起こすための呼び出しが必須な状況で、このエントリで取り上げている話題が気になりますか?
toton
>Linuxなどでは、システムコールから戻るとき、割り込みハンドラ終了時の処理でコンテキストスイッチを実行するようです。
について調べたいのですが、どこらへんの資料を漁ればよいでしょうか?ご教授いただけると助かります!
syasuda
コメントありがとうございます。
このエントリは、通りすがりに見かけたOmicronのTikiに触発されて書きました。
つづきは最新のエントリで。
Linuxについて質問されて困るの巻
http://d.hatena.ne.jp/syasuda/20090118/1232289896
toton
自分は経験で、重いループでシステムコール発行しないとかでプロセスではなくOS全体が重くなるのではと思っていたのですが裏付けがなかったので調べてました。ありがとうございます!
syasuda
CPUは止まるということができないので、「何もしない」「無負荷」であるというのが実は幻想なんだと思います。NOPループをひたすた実行しているのが無負荷のはずです。
CPU使用率がゼロというのがどういう状態であるかある程度つかんでおくと、罠を避けることが出来ると思います。
あとは地道な仮説を立てて矛盾を掘り出していけば必要な解は見つかると思いますです。私にはそんな高度な仕事が回ってきたことないですがね。
CPUは止まれませんがバスは止まることがあります。CPU以外のものがバスを占有したらCPUは止まりますね。
I/Oがバスを占有して、CPUの邪魔をするのは良くある風景です。
その場合プロセスはぜんぜんCPUを占有していないのに、仕事が進まないのです。
I/Oバスの占有率もTOPコマンドで簡単に見れればいいのに、と思いますがCPUやチップセットごとに構成がばらばらなので難しいんでしょうかねぇ。
solarisあたりなら妙なツールがあるような気もしますが。diagなんちゃらだったかな。
たまにはひとつの仕事をじっくりやってみたいものですな~。