boost::threadのクラスを使ってマルチスレッド化したDXライブラリにおいて、
メインスレッドで定期的にProcessMessage(void)を呼んでいても、サブスレッドで入力が不定期に途切れる現象を確認したので報告させていただきます。
発生条件を私なりに調べたところ、サブスレッドでProcessMessage(void)やScreenFlip(void)等の関数を呼ばない時、この挙動が確認されました。
過去ログ(ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=2507)にて、
標準関数を使って作られたマルチスレッドでも、同じ条件下で同じ現象が確認されました。
以下私の環境と再現コードです
OS: Windows 7
メモリ: 8GB
CPU: AMD A8-4500M
GPU: Radeon HD7640G + 7470M 1GB
コンパイラ: Microsoft Visual Studio 2013
#include <process.h>
#include "DxLib.h"
#include "boost\thread.hpp"
#include <iostream>
#define BOOST true
volatile int g_ProcessThreadFlag;
volatile int g_FuncThreadFlag;
bool p;
unsigned WINAPI func(void *pArg){
p = false;
int i = 0;
while (g_ProcessThreadFlag == 0) {
int input = GetJoypadInputState(DX_INPUT_PAD1 | DX_INPUT_KEY);
bool n = input & PAD_INPUT_1 ? true : false;
if (n != p){
std::cout << "change " << n << " "<< i << std::endl;
p = n;
}
++i;
ScreenFlip(); //ここをコメントアウトすることでバグが発生します
if (input&PAD_INPUT_2)break;
}
g_FuncThreadFlag = -1;// このスレッドが終了したフラグ
if(!BOOST) _endthreadex(0);
return 0;
}
unsigned WINAPI funcForWindows(void *pArg){
return func(pArg);
}
void funcForBoost(){
func(NULL);
}
int _tmain(int argc, _TCHAR* argv[])
{
CRTDBG;
g_ProcessThreadFlag = 0;
SetWaitVSyncFlag(FALSE);
ChangeWindowMode(TRUE);
SetMultiThreadFlag(TRUE);
if (DxLib_Init()){ return -1; }
SetDrawScreen(DX_SCREEN_BACK);
if (BOOST){
boost::thread t1(funcForBoost);
while (!ProcessMessage() && g_FuncThreadFlag == 0) {
Sleep(10);//少しCPUを休める
}
}
else{
HANDLE hTh;
unsigned thID;
g_FuncThreadFlag = 0;
hTh = (HANDLE)_beginthreadex(NULL, 0, funcForWindows, 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;
}
※printDXでも上記の条件に当てはまるようなので、コンソールアプリケーションとしてプロジェクトを作成しています。