トップページ > 過去ログ > 記事閲覧
マルチスレッド時のキー入力について
名前:すにー 日時: 2012/01/01 16:54

マルチスレッドの実験用に以下のコードを書いたのですが、スレッドに入ると入力が出来なくなりました。 どなたかお願いします。 #include<process.h> #include"DxLib.h" CRITICAL_SECTION CsDraw; CRITICAL_SECTION CsInput; CRITICAL_SECTION CsSound; unsigned WINAPI func(void *pArg){ EnterCriticalSection(&CsDraw); EnterCriticalSection(&CsInput); int i=0; while(!ProcessMessage()) { printfDx(TEXT("%d\n"),i++); if(i>300){ break; } printfDx(TEXT("%d\n"),CheckHitKeyAll()); ScreenFlip(); ClearDrawScreen(); clsDx(); } LeaveCriticalSection(&CsDraw); LeaveCriticalSection(&CsInput); _endthreadex(0); return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ChangeWindowMode(TRUE); SetMultiThreadFlag(TRUE); if(DxLib_Init()){ return -1; } SetDrawScreen(DX_SCREEN_BACK); InitializeCriticalSection(&CsDraw); InitializeCriticalSection(&CsInput); InitializeCriticalSection(&CsSound); HANDLE hTh; unsigned thID; hTh = (HANDLE)_beginthreadex(NULL, 0, func, NULL, CREATE_SUSPENDED, &thID); if(!hTh){ return -1; } EnterCriticalSection(&CsDraw); EnterCriticalSection(&CsInput); int i=0; while(!ProcessMessage()) { printfDx(TEXT("%d\n"),i++); if(i>300){ break; } printfDx(TEXT("%d\n"),CheckHitKeyAll()); ScreenFlip(); ClearDrawScreen(); clsDx(); } LeaveCriticalSection(&CsDraw); LeaveCriticalSection(&CsInput); ResumeThread(hTh); WaitForSingleObject(hTh, INFINITE); CloseHandle(hTh); DxLib_End(); return 0; } TEXTマクロを使っていますが、マルチバイトでやっても同じでした。 環境はVC++です

Page: 1 |

Re: マルチスレッド時のキー入力について ( No.1 )
名前:タカトゥ 日時:2012/01/01 17:18

ProcessMessage() は一つのスレッドで、 ScreenFlip() ClearDrawScreen() および描画系の関数も一つのスレッドで行なってください。 printfDxもおそらく一つのスレッドで行ったほうがいいと思います。 私はProcessMessage()だけを行うスレッドと描画等を行うスレッド、ファイルをロードするスレッドというように分けています。
Re: マルチスレッド時のキー入力について ( No.2 )
名前:softya(ソフト屋) 日時:2012/01/01 17:22

DXライブラリはスレッドセーフじゃない(つまりスレッド不可)なのでスレッドでDXライブラリの関数は基本使用禁止ですよ。
Re: マルチスレッド時のキー入力について ( No.3 )
名前:通りすがり 日時:2012/01/01 18:55

ループ内で LeaveCriticalSection を呼んでいないのが原因ではないでしょうか? ただ、タカトゥさんの指摘通り ProcessMessage を 複数のスレッドから呼んでいるのでまともに動かないと思いますが
Re: マルチスレッド時のキー入力について ( No.4 )
名前:すにー 日時:2012/01/01 20:49

このコードでやりたかったことはwinmainでテストしたあとでResumeThreadを使ってスタートさて、 同じ事をスレッドで行うというものです。まだ学習中なので同時に走らせることはしてません。 いくつかの種類の関数を"同時に"扱ってはいけないとは思っていたのですが、 何らかの方法で絶対に同時には呼び出さないようにしてもアウトなのでしょうか。 あと、winmain内のループをコメントアウトしてもだめでした。 私の環境だけでしょうか
Re: マルチスレッド時のキー入力について ( No.5 )
名前:タカトゥ 日時:2012/01/01 21:03

DXライブラリでマルチスレッドをやるのであればこのようになると思います。 #include<process.h> #include"DxLib.h" volatile int g_ProcessThreadFlag; volatile int g_FuncThreadFlag; unsigned WINAPI func(void *pArg){ int i=0; while(g_ProcessThreadFlag == 0) { printfDx(TEXT("%d\n"),i++); if(i>300){ break; } printfDx(TEXT("%d\n"),CheckHitKeyAll()); ScreenFlip(); ClearDrawScreen(); clsDx(); } g_FuncThreadFlag = -1;// このスレッドが終了したフラグ _endthreadex(0); return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { g_ProcessThreadFlag = 0; ChangeWindowMode(TRUE); SetMultiThreadFlag(TRUE); if(DxLib_Init()){ return -1; } SetDrawScreen(DX_SCREEN_BACK); HANDLE hTh; unsigned thID; g_FuncThreadFlag = 0; hTh = (HANDLE)_beginthreadex(NULL, 0, func, NULL, 0, &thID); if(!hTh){ return -1; } while(!ProcessMessage() && g_FuncThreadFlag == 0) { Sleep( 10 );//少しCPUを休める } g_ProcessThreadFlag = -1;// このスレッドが終了したフラグ WaitForSingleObject(hTh, INFINITE); CloseHandle(hTh); DxLib_End(); return 0; }
Re: マルチスレッド時のキー入力について ( No.6 )
名前:すにー 日時:2012/01/01 21:14

タカテゥさんの方法なら出来ました。 ProcessMessageは必ずmainの(DxLib_Initを呼んだ?)スレッドから呼ばなければならない、ということですね。
Re: マルチスレッド時のキー入力について ( No.7 )
名前:タカトゥ 日時:2012/01/01 22:07

>>ProcessMessageは必ずmainの(DxLib_Initを呼んだ?)スレッドから呼ばなければならない、ということですね。 別にそういう訳ではありません。 呼ぶスレッドを1つにするべきだということです。
Re: マルチスレッド時のキー入力について ( No.8 )
名前:すにー 日時:2012/01/01 23:05

EnterCriticalSection(&CsDraw); EnterCriticalSection(&CsInput); int i=0; while(!ProcessMessage()) { printfDx(TEXT("%d\n"),i++); if(i>300){ break; } printfDx(TEXT("%d\n"),CheckHitKeyAll()); ScreenFlip(); ClearDrawScreen(); clsDx(); } LeaveCriticalSection(&CsDraw); LeaveCriticalSection(&CsInput); をコメントアウトした時も反応しなかったので mainのスレッド以外から呼んだらおかしくなるのだと思ったのですが・・・ また、全く別の時にも別のスレッドから呼び出してもいけない、ということは 最初に呼ばれたときにそのスレッドのIDか何かを保存していることになると私は思うのですが、(DxLib_Initでやってると思った)そんなことをやっているのでしょうか。
Re: マルチスレッド時のキー入力について ( No.9 )
名前:すにー 日時:2012/01/02 09:19

追記:コメントアウトしたのはmainの中のです
Re: マルチスレッド時のキー入力について ( No.10 )
名前:softya(ソフト屋) 日時:2012/01/04 12:59

とりあえず、スレッドに関して管理人さんの 「マルチスレッド化においてキー入力が取得できない」 ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1683 など制約があるようなのでmainでProcessMessage()した方が良いと思います。
Re: マルチスレッド時のキー入力について ( No.11 )
名前:すにー(解決) 日時:2012/01/04 13:26

そういう仕様にしかならなかったのですね。 マルチスレッドを使う際はタカトゥさんの方法でやりたいと思います

Page: 1 |