トップページ > 記事閲覧
マルチスレッドで安全に使える関数は?
名前:MKII 日時: 2019/11/19 21:22

普通にシングルスレッドでゲームループを書くと、VSync の副作用で毎秒入力情報取得出来る回数が制限されます。 そこで描画、ScreenFlip、VSync を別スレッドで処理し、マルチスレッドのプログラムを組んでます:  game.cs (main)   pastebin.com/PNRNWvbF  renderer.cs   pastebin.com/0La2jyN7 現状二つスレッドに分けでDXライブラリの関数を使ってます:  メインスレッド:   DxLib_Init()   ProcessMessage()   CheckHitKey()   DxLib_End()   (将来的に音楽・効果音もメインスレッドに処理したい)  レンダリングスレッド:   ClearDrawScreen()   DrawBoxAA()   DrawString()   ScreenFlip()   WaitVSync() 結構いい感じに動いてるけど、何処で「DXライブラリの関数は基本 DxLib_Init() を呼んだスレッド以外に使えない」読んだ記憶がある… DxLib_Init() を呼んだスレッド以外のスレッドで安全に使える関数のリストはありますか?
メンテ

Page: 1 |

Re: マルチスレッドで安全に使える関数は? ( No.1 )
名前:管理人 日時:2019/11/19 23:32

> 結構いい感じに動いてるけど、何処で「DXライブラリの関数は基本 DxLib_Init() を呼んだスレッド以外に使えない」読んだ記憶がある… >  > DxLib_Init() を呼んだスレッド以外のスレッドで安全に使える関数のリストはありますか? DXライブラリは複数のスレッドから呼ばれることを考慮していない設計なので、基本的に DxLib_Init を呼んだスレッド以外のスレッドで安全に使えることを保証している関数はありません ただ、MKIIさんがされているように1分類の関数を1つのスレッドでのみ呼ぶのであれば問題なく 動作する可能性は高いと思います ただ、あくまで『問題なく動作する可能性がある』なので、自己責任の上でご使用ください m(_ _)m
メンテ
Re: マルチスレッドで安全に使える関数は? ( No.2 )
名前:MKII 日時:2019/11/21 12:16

ご返事ありがとうございます。 「1分類の関数を1つのスレッドでのみ呼ぶ」 具体的に関数の分類はどんな感じでしょう? 例えば、現在レンダリングスレッドで VBLANK 時間を計るため WaitVSync(1) を使ってます。   関数リファレンスページにはこのような一文がある: 「なお止まっている間は常に『ProcessMessage』関数を実行しています。」 メインスレッドで入力情報取得する度に ProcessMessage() を呼んでますか、これは二つのスレッド同時に使うことになってます。 テスト中一切異常は発生してないけど…これはいいのか?
メンテ
Re: マルチスレッドで安全に使える関数は? ( No.3 )
名前:管理人 日時:2019/11/21 23:29

> 「1分類の関数を1つのスレッドでのみ呼ぶ」 >  > 具体的に関数の分類はどんな感じでしょう? 明確な区切りはありません 大雑把に『画面系』『音系』『入力系』などでしょうか ただ、あくまで『1分類の関数を1つのスレッドでのみ呼ぶのであれば問題なく動作する可能性は高い』なので、 例えば LoadGraph と LoadSoundMem は前述の分類では別分類ですが、どちらもファイルにアクセスするので 同時に呼ばれると問題が発生するかもしれません > テスト中一切異常は発生してないけど…これはいいのか? お察しの通り ProcessMessage が同時に実行される可能性があるので、問題が発生する可能性は比較的高いと思います ( 同時に実行されれば必ず問題が発生するわけではありませんが )
メンテ
Re: マルチスレッドで安全に使える関数は? ( No.4 )
名前:MKII 日時:2019/11/23 20:27

> 例えば LoadGraph と LoadSoundMem は前述の分類では別分類ですが、どちらもファイルにアクセスするので > 同時に呼ばれると問題が発生するかもしれません なるほと、確かそれは考えて無かった。ならば全てのファイルにアクセスする系をメインスレッドにします。 ーーーーーーーーーー DxLibMake のコード中に WaitVSync を検索しましたが、実は ProcessMessage() を呼んでない様子です。 実際 WaitVSync(1200) で試しましたが、待っている間ウインドウが移動できなくなりました。 関数リファレンスページの間違いでしょう?  dxlib.xsrv.jp/function/dxfunc_other.html#R6N2 もし記述通り呼ぶように修正しますなら、是非 WaitVSync(1) の場合例外どうして呼ばないで欲しい。
メンテ
Re: マルチスレッドで安全に使える関数は? ( No.5 )
名前:管理人 日時:2019/11/25 01:53

> DxLibMake のコード中に WaitVSync を検索しましたが、実は ProcessMessage() を呼んでない様子です。 ソースコードを確認してみたところ Direct3D 11 を使用する場合は内部で ProcessMessage を呼んでいませんでしたが、 Direct3D 9 を使用する場合は内部で ProcessMessage を呼んでいました > もし記述通り呼ぶように修正しますなら、是非 WaitVSync(1) の場合例外どうして呼ばないで欲しい。 Direct3D 11 の処理はそのままで、Direct3D 9 の処理はご要望の通り WaitVSync(1) の場合のみ ProcessMessage を呼ばないようにしてみましたので、よろしければお試しください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい)
メンテ
Re: マルチスレッドで安全に使える関数は? ( No.6 )
名前:MKII 日時:2019/11/30 02:52

返事が遅くなってすみません。 > Direct3D 11 を使用する場合は内部で ProcessMessage を呼んでいませんでしたが、 > Direct3D 9 を使用する場合は内部で ProcessMessage を呼んでいました > Direct3D 11 の処理はそのままで、Direct3D 9 の処理はご要望の通り WaitVSync(1) の場合のみ > ProcessMessage を呼ばないようにしてみましたので、よろしければお試しください m(_ _)m それは逆の気がする...? 試しましたが、依然待っている間ウインドウが移動できない。 ーーーーーーーーーー もし関数リファレンスページ通り「止まっている間は常に『ProcessMessage』関数を実行」するなら: 1)Direct3D 9 の処理はそのままで(既に ProcessMessage を呼んでいました) 2)Direct3D 11 の処理は関数リファレンスページ通りに修正(ProcessMessage を呼ぶ)する かつ個人的の要望で、 3)両方 WaitVSync(1) の場合、ProcessMessage を呼ばない。 度々お手数をおかけしました。
メンテ
Re: マルチスレッドで安全に使える関数は? ( No.7 )
名前:管理人 日時:2019/12/01 23:36

すみません、WaitVSync の動作については現在のまま変更する予定は無い為、リファレンスの方を修正しました Direct3D 11 の処理で ProcessMessage を呼ばない理由としましては 『Direct3D 9 使用時に ProcessMessage を呼ぶために使用している API と同等の機能を持った API が Direct3D 11 には無い為』です Direct3D 9 で動作させている場合は Direct3D 9 より更に古い API である DirectDraw 7 の機能を使用して 垂直同期中かを検出しているのですが、同等の機能が Direct3D 11 時代の API には無く、且つ DirectDraw 7 の 機能が何時使えなくなるか分からない為、Direct3D 11 を使用する場合は DirectDraw 7 の機能に頼った処理は 行わないようにしようと考えています
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存