对不起,如果标题不是我的问题所问的。我有点不确定问这个问题的最佳方式。
基本上,我创建了一个 DirectX C++ 应用程序,它当然利用了 Win32 函数。所以我有下面的静态方法
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
上面的方法中包含以下 case 语句。
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();” 在为继续绘制 DirectX 图形而启动的 while 循环中调用。
那么上面的代码是否安全执行,或者当两个线程都在相同的值上执行某些事情时我会遇到问题?
我对处理 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;
}