• 締切済み

ファイルアクセスより先にCPUやメモリが動くことはありますか?

現在、画像の表示などを行うプログラムを、VC++2005で記述しています。 (.NETではなく、DirectXでもなく、Win32APIを使っています。) 次のような問題が起きたのですが、原因がはっきりしませんので、 ご助言いただければと思います。 マウスカーソルが重なった時点で画像を即時に表示する、という動作を 記述したのですが、うまくいかない時には、画像が出ません。 (ちゃんと表示されたりされなかったりします。) また、他人の高速なマシン環境で動作させると、それだけでなく、 他の大量の画像を読み込み・出力する処理が、正常に動きません。 つまり、画像が表示されないのですが・・・。 一応、推測される原因としては、次のように考えています。 画像を表示するには、まずBMPへのファイルアクセス、続いて メモリに乗せて、最後にウィンドウを再描画して表示、となりますが、 この、最初のファイルアクセスが終わらないうちに、 もしかすると次の処理が走ってしまっているのではないか、 と想像されます。 根拠としては、先に記述した現象からの想像なのですが、 <1> マウスを何度もかぶせ、何度もファイルアクセスさせる、ということは その回数分だけファイルアクセスが起きているということであり、 メモリやCPUはついていけても、ディスクは間に合わないでいるのでは ないか、と思われたこと <2> 高速なマシンで動かすと画像の取得に失敗するのに、低速なマシンで 動かすと正しく表示される(OSなどの環境は同じです)、ということは、 つまり、ディスクと、メモリ+CPUとの間の速度のギャップが大きい、 ゆえにディスクが取り残されてしまったためではないか、と思われたこと 勿論、マウスオーバーイベントで毎回ディスクアクセス、なんて作り自体 まずいのはわかっていますので、これは何れ修正しますが、 ただ、上記のような推論は正しいのでしょうか? もし正しいとすれば、どのような処理を記述すれば、 この現象を防ぐことができますでしょうか? どなたか教えてくださればと思います。 よろしくお願い致します。

みんなの回答

noname#50176
noname#50176
回答No.2

ファイルを介したディスクアクセスは同期処理ですから アクセス元のスレッドにはシーケンシャル処理になるはずです。 ですから1回のアクセスでしたら同期ずれは起きません。 ただし2回目以降はシノニムが発生する可能性があります。 これを防ぐため排他制御による占有ロックをかけて同スレッド の重複アクセスであっても競合を防ぐわけです。 LockFile 関数がこれに当たります。

StoneTouch
質問者

お礼

ご回答くださいまして、ありがとうございます。 ええと、LockFileというと、私は 「一つのファイルに複数のアクセスがあった場合、 複数の場所で読み書きが発生すると滅茶苦茶になってしまうので、 順番にアクセスさせるために、読み書きする誰かが、ファイルを占有する」 という使い方をするのはわかっているのですが・・・。 つまり、こう考えてよろしいでしょうか。 「一つの処理で、複数の画像ファイルにアクセスするが、 一つ目のファイルにアクセスし終わる前に次のファイルアクセスが 開始されたりなどして、順序が前後してしまい、そうしたことが原因で 正しい画像表示ができなくなる」 すみません、正直、少しピンとこない感じはします。 (正しく理解できていないだけなのかもしれませんが・・・。) ですが、せっかくいただけたアドバイスですので、 参考にしていろいろ調べてみようと思います。 ありがとうございました。

回答No.1

C++の標準関数ではなく、Win32API で、CreateFile() を使うと、バッファにデータがたまる前に、ReadFile() すると、取りこぼしが起こったような気がします。 ClearCommError(handle, &ErrorMask, &comstat1); などとすると、comstat1.cbInQue にバッファにあるデータの数がセットされたような気がしますので、それを確認してから(確かにデータがあるとわかってから)その数を ReadFile() したような。 記憶が定かではありません。

StoneTouch
質問者

お礼

ご回答くださいまして、ありがとうございます。 ClearCommErrorで解決できるかどうかは、現在、調査中です。 とりあえず、CreateFileでデータの取りこぼしがありえるらしい、 ということがわかっただけでも、対処の方針を検討できます。 場合によっては、もう無理やりに、使用する画像を、使うずっと前に 全部読み取って、メモリ上に持ちっぱなしにする、という ダサい方法で対処するかもしれませんが・・・。 引き続き、自分でもいろいろ調べてみますが、 とにかくありがとうございました。

関連するQ&A