マルチスレッドの動作停止について

このQ&Aのポイント
  • C++とDirectXを使用して作成しているマルチスレッドプログラムが動作を停止してしまいます。停止する原因について教えてください。
  • マルチスレッドプログラムでの動作停止の可能性のある原因を特定するために、以下の状況を調査しました。1. 初期の読み込み時にのみマルチスレッドを使用している。2. 読み込んでいるものは3Dモデルと2D画像。3. 動作停止は3〜4回に1回の割合で発生。4. 停止する位置は毎回異なる。5. スレッドセーフであるがデッドロックは起こっていない。6. エラーは例外が出ない。
  • マルチスレッドプログラムが動作を停止する原因を調査しています。停止する位置が毎回異なるため、特定の原因を特定するのは難しいですが、以下の状況が考えられます。1. リソース競合が発生している可能性がある。2. メモリのアクセスエラーが発生している可能性がある。3. スレッド間の同期がうまく行われていない可能性がある。停止する原因を見つけるために、コードを詳細に調査してください。
回答を見る
  • ベストアンサー

マルチスレッドの動作停止について質問なんですが

マルチスレッドの動作停止について質問なんですが 現在、C++とDirectXを使用してマルチスレッドプログラムを作成しているのですが、 どういう訳かプログラムそのものが動作停止を起こしてしまいます 状況としては 1、マルチスレッドは初期の読み込み時にのみ使用していて、毎回同じものを同じ順番で読み込んでいる。 2、読み込んでいるものは3Dモデル、2D画像の二つ 3、毎回動作を停止する訳ではなく、3~4回に1回の割合で停止する 4、動作を停止している位置を調べてみると毎回違う箇所で動作を停止している 5、スレッドセーフで作っており、デッドロック等は起こっていない 6、エラーは例外は出ない 以上の状況で、プログラムの停止する可能性のある原因について心当たりがある方がいれば教えていただきたいです

質問者が選んだベストアンサー

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.2

このページにあるように、 http://d.hatena.ne.jp/ho_5750/20120417/1334670243 >IDirect3DDevice9::Present をウィンドウメッセージを処理するスレッドとは別のスレッドから呼び出すと、この Present で固まることがあるというものでした。 のような処理はないですか?

bypass000
質問者

お礼

回答ありがとうございます。 確認したところ、確かに別スレッドからデバイス制御を行っている場所があります。 ここの処理をメインスレッドにまとめたところ確かにとまらなくなりました。 いろいろと無知ですみません。 わざわざ調べてまでいただいて本当にありがとうございます

その他の回答 (1)

回答No.1

動作停止ということは、アプリからOSに処理が戻らないということですよね。 エラーが出ていないということであれば、スレッド本体、もしくは、そのスレッドを制御している処理自体で、どこかループしてしまっているか、読み込み処理に時間がかかりすぎて動作停止しているのではないでしょうか。 スレッドの実装方法自体が間違っているということは無いですよね?

bypass000
質問者

お礼

回答ありがとうございます。 ループして動作が遅いというよりは、完全に「応答無し」状態になってしまっていて、タスクマネージャーからでしか起動したエグゼファイルを終了できない状態」です いろいろと試してみた結果、毎回フリーズしてしまうのはマルチスレッドの方ではなく本スレッドのロード画面を描画しているスプライトのLPDIRECT3DDEVICE9の>Presentのあたりみたいです スレッドの実装方法ですがDirectXのLPDIRECT3D9のCreateDeviceで 「D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED」 と記述してマルチスレッドを使用しています

関連するQ&A

  • マルチスレッドでのDirectXの使用について質問なのですが

    マルチスレッドでのDirectXの使用について質問なのですが 現在_tWinMain内でゲーム用スレッドを登録して スレッド内でDirectXの初期化と解放を行っています それでプログラム終了の際に Direct3D9: (ERROR) :Final Release for a device can only be called from the thread that the device was created from. と出て悩んでいます。 googleで調べてもそれらしいところが見当たらないので困ってます・・・ 解決方法があればぜひよろしくお願いします。

  • マルチスレッドの同期方法

     マルチスレッドで以下のような内容のプログラムを組みたいのですが、当方マルチスレッド超初心者で、ミューテックス、セマフォの基本的な使用方法は習得したつもりですが、この問題を解決する方法が見当もつきません。解決方法をご存知の方がいらっしゃいましたら、ご教授お願いします。  スレッドは全部で6本あります。そのうち、1本は初期状態では、停止しています。他のスレッド5本は、初期状態で動作を始めています。この5本のスレッドはそれぞれ決められたポイントで、何らかの方法で、一時停止をさせます。この5本のスレッドすべてがそれぞれのポイントで停止した時点で、初期状態で停止していた1本のスレッドが動き出し、今度は、このスレッドを決められたポイントに来た時点で、停止させます。停止が確認できたら、止めていた5本のスレッドを一挙に稼動させます。あとはこれの繰り返しです。  環境はWinXp, VC2005 です。

  • マルチスレッドのデバッグ

    Eclipseでマルチスレッドプログラミングをしています。 アプリケーションの特性上スレッド数が非常に多く、普通に実行すると稀にデッドロックが起きるが、デバッグの手順によってはそのバグが表れなかったりして、自分自身が効率良くデバッグを行えていない気がします。 Eclipseでデバッグをするにあたり、何か知っておくと便利な機能等ありますか? 現在はスレッドを全て停止して、ちまちまと1つずつStep in/over しています。 オブジェクトの待機プールにどのスレッドが入っているかを知りたいのですが、知る方法ってあるでしょうか?

    • ベストアンサー
    • Java
  • マルチスレッドプログラミングについて

    現在DirectXでマルチスレッドを使ってプログラムを組んでいますが、その処理の中で描画のみを切り離してスレッド化しようと思っています。 そこで質問ですが、描画スレッドに渡す処理の個数が多い場合は描画スレッドを2つにして処理する個数も分けたほうが処理は早くなるのでしょうか?

  • マルチスレッドについて

    現在”猫でもできる”の87、88章を学んでおります。 まず87章でマルチスレッドの根本的なやり方を学びましたが、いきなり疑問が浮かびました。 _beginthread関数によりスレッドをスタートさせ、この関数で登録した関数内で_endthread関数を実行し終了させていることは分かります。 しかし_beginthread関数で登録した関数に引数を渡す処理がどの部分で行われているのかわかりません。 登録する関数はvoid型で引数はvoid*型でなければいけないことは分かったのですが、プログラムのどこを見てもこの登録した関数に引数を渡す処理が行われていません。 その辺の動作の説明を分かる方でいいのでよろしくお願いします。 そして88章では排他制御のマルチスレッドを行うプログラムの製作を行っているのですが、ちょっとした疑問が浮かびました。 EnterCriticalSection関数、LeaveCriticalSection関数ではさまれたプログラムは排他制御され他からアクセスされない。 この関数はこんな理解で良いんですかね? この理解で行くと、88章で説明していきますが、子ウィンドウを2つ作成しそれぞれのプロシージャ内で排他制御された関数をスレッドとしてスタートしています。 この2つのスレッドの動作についてですが、互いに排他制御関数が記述されているため、動作としてはまず左の子ウィンドウのスレッドが処理されている場合、右の子ウィンドウのスレッドは停止している。そして左の子ウィンドウのスレッドの排他制御が解放されたときに、右の子ウィンドウのスレッドが開始する。 そしてあるとき左の子ウィンドウのクライアントウィンドウ内で右クリックされた場合、その時点で排他制御されたスレッドが終了するのを待ち、終了したらcountを+1する。 こんな動作が行なわれていると理解してよいのでしょうか?

  • C# マルチスレッドにおける例外処理

    下記のようなデリゲートを利用したマルチスレッドのプログラムを組みました。 しかし、マルチスレッド内で例外がおきても、正常にプログラムが終了してしまいます。 (try-catchでも例外を捕捉できません) マルチスレッドプログラムにおいて、例外を捕捉するにはどうすれば、いいのでしょうか? using System; using System.Threading; class Class1 { delegate void delg(); public static void Main() { delg d = new delg(multi); d.BeginInvoke(new AsyncCallback(call), null); //マルチスレッド開始 System.Threading.Thread.Sleep(500); //マルチスレッドで例外を強制的に投げているので、 //ここまでたどり着く前にアプリケーションが落ちるはず。 //しかし、実際には正常終了。 Console.WriteLine("メインメソッド 正常終了"); } public static void multi() { Console.WriteLine("マルチスレッドで実行中"); throw new Exception(); //例外を強制的に投げる。 } public static void call(IAsyncResult ar) { Console.WriteLine("コールバックメソッド実行"); } }

  • マルチスレッド化。

    今とても大きな配列を使用し、長時間処理をするプログラムを組んでいます。元々処理時間に1時間を要するプログラムを2分で処理を完了するまでに仕上げました。 しかし、探究心はおさまらずもう少し高速化に挑みたいと考えています。 過去に「猫でもわかる」のSDK第1章と2章を学び、マルチスレッドのプログラムをSDKで組んだことがあります。それを利用してマルチスレッド化を実現したいと考えています。 言語はCでVisualStudio2005を使用しています。 *疑問1   SDKの場合WinMain関数とプロシージャからの実行で_beginthread関数を記述すれば処理が開始されます。 Cでもmain関数内に記述すれば、SDKと同様に処理できるのでしょうか? *疑問2 _beginthread関数の引数に関してです。 第1引数にvoid型のスレッド関数、第2引数に0?、そして第3引数にはスレッド関数に渡すデータの引数を記述すると把握しているのですが、渡したいデータは複数あり、***型と**型、それに変数を数個とスレッド関数に渡したいデータだらけなのですが、どのように記述すればよいでしょう? *疑問3 2つのスレッドを作成しようと考えていますが、その2つのスレッドで1つの大きな配列を共有して処理したいと考えています。 そのため、スレッド間の同期が必要になるわけですが同期の種類にもクリティカルセクションやミューテックス、イベントと豊富でどれを使用すれば良いのか迷ってしまいます。厳密に同期を取り処理をするにはイベントが一番良いと考えています。 これらの疑問に答えられる方はアドバイスをよろしくお願いします。

  • マルチスレッドについて。

    今、大きな配列を元に処理を行うプログラムを作成しています。 シングルスレッドでも十分速度を向上するようチューニングに成功しましたが、マルチスレッド化をすればさらに速度を向上させることができるだろうと考え、先日マルチスレッドかに成功しました。 しかし・・・奇妙な現象が起こりました。 マルチスレッドで性能を引き出すには、排他制御はないほうが良いと考え、メモリは食いますがスレッドに与える入力情報(大きな配列)を2つ用意し、排他制御なしの2スレッドを実行できるようにしました。しかしやはりメモリを消費しすぎてしまうため、配列にアクセスする部分のみ排他制御を行うようクリティカルセクションを設定し入力情報を2スレッドで共有して処理を行うよう組み替えました。 結果、やはり排他制御なしの場合よりはるかにスピードダウンしてしまい、シングルスレッドより少し早い処理時間で終了してしまいました。 余りにも悔しいため、ちょっと危険な実験だとは思いましたが、入力情報を2つのスレッドで共有しているにもかかわらず、排他制御の部分、つまりクリティカルセクションを取り除いて実行してみようと考えました。予想としては同時にアクセスし衝突が起きてエラーで停止してしまうと考えましたが・・・・・・ 結果なぜかエラーなく処理をし続け、普通に終了してしまいました。 これはなぜでしょう? 偶然にも共有情報に同時にアクセスすることがなかったためでしょうか?

  • 時計は動作を停止しました

    パソコンを起動すると毎回「時計は動作を停止しました」と出て、「問題が発生したためプログラムが正しく動作しなくなりました。解決策がある場合はWindowsから通知されます」と出てきます。 表示されないようにするにはどうしたら良いですか?

  • バイオ5の動作停止原因は何が考えられますか? 

     昨日(2013/02/28)からバイオ5のDirectX10バージョンでチャプターまたはマーセナリーズをやったら突然フリーズし、図のような     「プログラムが正しく動作しなくなりましたので、動作を停止しました。」 といったようなウィンドウが出てきてプログラムを終了させられます。ベンチマークテストも動作が停止しました。昨日以前は普通にDirectX10で障害なくプレイできていました。  また、DirectX9.0cの方ではそのようなことは起こらず、ベンチマークテストもSランクでした。  このままDirectX9.0cでプレイし続けることも可能ですが、原因がわからないままでは今後のゲーム購入に支障が出てしまいますのでできるだけ原因を解明させておきたいです。  下記にPCスペックを載せておきますので、僕のPCでの動作停止の原因とできたらその解決策をお教えください。 OS : Windows 7 Home Premium 64bit BIOS : Ver:04.06.05 プロセッサ : Intel(R) Core(TM) i7-3770 3.40GHz メモリ : 8GB DirectX : DirectX 11 ビデオチップ : GeForce GTX650 VRAM : 4045MB ディスプレイモード : 1920*1080 (32bit) P.S. バイオ5の推奨スペックです↓ http://www.capcom.co.jp/bio5/pc_spec.html#pc_spec

専門家に質問してみよう