很抱歉,如果标题不是我的问题。我有点不确定最好的问题。
基本上我已经创建了一个DirectX C ++应用程序,它当然使用Win32函数。所以我有下面的静态方法
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
上述方法中包含以下案例陈述。
case WM_INPUT:
{
unsigned __int32 dwSize;
GetRawInputData((HRAWINPUT__*)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
unsigned char *lpb = new unsigned char[dwSize];
GetRawInputData((HRAWINPUT__*)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
tagRAWINPUT* raw = (tagRAWINPUT*)lpb;
InputSystem::handleRawMessage(raw);
delete[] lpb;
}
break;
好了,方法 InputSystem :: handleRawMessage(raw); 执行以下操作。
__int32 KEY_STATE[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void InputSystem::handleRawMessage(tagRAWINPUT *raw)
{
if (raw->header.dwType == RIM_TYPEKEYBOARD)
{
int key = raw->data.keyboard.VKey & 0xFF;
KEY_STATE[key >> 5] |= 1 << (key & 0x1F);
}
}
所以我假设WindowProc是一个单独的线程,所以我让它访问这些数组并将值存储到它们。好吧,我觉得可能会出现问题,但我不确定这是否安全,因为只有1个方法读取,1个方法写入。
void InputSystem::handleInput(void)
{
PREVIOUS_STATE = CURRENT_STATE;
CURRENT_STATE = 0;
for (int i = 0; i < MAPPING_SIZE; ++i)
{
if (isKeyPressed(MAPPED_KEYS[i]))
{
CURRENT_STATE |= 1 << i;
if (PREVIOUS_STATE & 1 << (0x10 | i))
CURRENT_STATE |= 1 << (0x10 | i);
}
}
clearKeyStates();
}
bool InputSystem::isKeyPressed(unsigned __int8 key)
{
return (KEY_STATE[key >> 5] & 1 << (key & 0x1F)) != 0x0;
}
上面的代码“InputSystem :: handleInput();”在启动的while循环中调用,以便继续绘制DirectX Graphics。
上面的代码是安全的执行,还是当两个线程在同一个值上执行某些操作时会遇到问题?
我对处理Win32的任何事情都很陌生,而且我最近才进入DirectX并不是因为DirectX与此有任何关系。我从来没有真正需要过多地担心并发性,所以我从来没有这样做,但我想了解这种特殊情况以及其他可能安全且不安全的情况。感谢。
while循环由以下代码生成..
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Dx3DEngine engine = Dx3DEngine(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
int code = engine.run();
if (code != 0)
{
engine.createUnsupportedWindow(code);
}
return code;
}
int Dx3DEngine::run()
{
MSG msg;
msg.message = WM_NULL;
__int64 cntsPerSec = 0;
__int64 prevTimeStamp = 0;
__int64 currTimeStamp = 0;
QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
const float secsPerCnt = 1.0F / (float)cntsPerSec;
while(msg.message != WM_QUIT)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
float dt = (currTimeStamp - prevTimeStamp)*secsPerCnt;
update(dt);
draw();
prevTimeStamp = currTimeStamp;
}
clean();
return (int)msg.wParam;
}