エムゲーム・ジャパン ゲーム ミィア ブログ サークル マイエム Login

兵どもの夢の跡

ブログチャンネル
yuki002さん
 
 ブログトップ   マイブログ   ランダムブログ    
ブログ型ブログ型タイトル一覧タイトル一覧
9.応答なし[ソフトウェア考]  
詳細/おすすめ(2197/0) | ソーシャルブックマーク(0)  2009/07/06 03:22

今回はゲームには直接関係ありません。

 

読者の皆様はゲームに限らず、特定のウィンドウが反応しなくなったという経験はお持ちでしょうか?

今回の話は、 応答なし についてです。

 

まず対処法だけは書いておきます。

注意事項として、この対処法は NT系OSで Windows 2000 以降を対象にしています。

それ以前の 95系OSの場合は「イベントドリブン型マルチタスク」と呼ばれており、

制御方法が NT系とは異なるからです。

そして 95系OSの場合には1つのウィンドウが応答しなくなると全体に影響します。

いわゆる フリーズ と呼ばれる現象です。 そしてリセットしか対処方法はありません。

 

ちょっと脱線しましたが NT系の対処法を書いておきます。

バージョンによって多少の差はありますがポップアップダイアログやタスクマネージャーで対応します。

通常ですと「このタスクは反応がありません。」などと画面にダイアログが出て、

強制終了と継続が選択できます。

タスクの復活を待つなら継続、あきらめるなら強制終了です。

タスクマネージャの場合もほぼ同じです。

タスク一覧に「応答無し」というタスクが表示されている筈です。

そのタスクを強制終了させる訳です。

 

さて、なぜこんな事が起こるのでしょう?

それはループ処理の遅延、または永久ループが発生しているからです。

NT系OSはタイムシェアリングを用いたマルチタスクシステムです。

あるウィンドウが応答しなくなっても、そのプログラムの実行時間が経過すれば別のタスクを実行できます。

その時、反応が無かったら「応答無し」とメッセージを出せるわけです。

95系では次のタスクを実行させるイベントが発生しなくなってしまうので、このような対処ができないわけです。

つまりNT系では無限ループであろうと処理遅延であろうと、

そのプログラムに与えられた実行時間が経過すれば次のタスクを実行できるという事ですね。

そのC言語プログラムコードを書いてみます。

while(1)

  ;

実にこれだけです。

while( 条件式 ) という構文は条件式が成立する期間は以下の処理をループするというものです。

C言語では 0=false(偽) ゼロ以外=true(真) としていますので、条件式=1では常に(真)なのです。

また直下の行には";"としか書かれていません。 つまり処理が無いのです。

言い換えれば「何もしない」を永久に繰り返す事を意味します。

 

こんなコード、故意に使う人はいません。

ですが条件式が常に(真)になってしまう場合があると永久ループに陥り、次の処理に進めません。

ところがOS側ではプログラム実行時間が決まっていて、永久ループ中でも一時的にOSに制御が移ります。

そして、この永久ループや処理が終わっていない場合「応答無し」という扱いになるのです。

 

処理遅延の場合、その処理が終わりループから抜けると新たな処理が可能になります。

これもOSが監視していて、今まで「応答無し」というステータスであったものが「実行中」に変わります。

 

 

さて、永久(無限)ループの正体と結果が判ったところで、

改めて注意しなければならない点を書いておきます。

先ほどのプログラムコードを、もう少し緻密に書いてみます。

A = 0;

while ( A < 10) {

 A ++;

}

これは変数Aを監視し、A が 10未満の場合に処理をループします。

そしてそのループ中に変数A が変化します。 この場合ですと A に1加算されます。

そして A が 10 になると次の処理に移ります。

 

これが正しい変数の使い方で、参照される変数はループ中に変更される必要があります。

処理系にもよりますが、変数Aの変化を監視しているのはループ内だけなのです。

このループは単純に時間待ち(wait)に使えそうですが、使ってはいけません。

使えるのはループ中に変数Aが変化する場合だけなのです。

ためしに変数Aが別の場所で変化するものとして以下のように書き直してみます。

変数Aは別の場所で変化する

while ( A < 10) {

 ;

}

このコードでは変数Aがループ外部でいくら変化しても影響を受けないからです。

それは変数Aがループ内部で変化するものとして実行されるからです。

外部は参照しません。 (もちろん外部を参照する処理系もあります。)

処理系依存なために、このようなコードを時間待ちに使うと無限ループに陥り

「応答無し」になってしまう場合もあります。

 

 

 

 

PS:

このようなコードの使い道はあるのでしょうか?

決して実用的ではないため、使い道はありません。 バグを発生させるだけ面倒が増え無駄になります。

使うのであれば「応答無し」にするためだけに使う事になります。

某読者様の画像で見た「おじいちゃん ⇒ 応答無し」というタスクマネージの絵がそれですね。

という訳で、そういうモノならば30分もあれば作る事ができます。

作ったとしてもまったく無意味なモノですが。

 

この記事のURL /  カテゴリ /  コメント(4)  / おすすめ  / 通報
   なぜ?
   規約の解釈について