我正在尝试使用QueueUserAPC
在特定线程上异步运行某些功能。当为x64编译时,我的代码可以正常运行,但是为x86编译并运行时,出现访问冲突。
我的文章结尾是一个最小的完整示例,它显示了我正在尝试做的事情(为简洁起见,省略了线程和事件的清理)。
在我的机器上,当我为“ x64”编译并运行时,我得到了预期的输出:
正在等待...
异步功能!
正在等待...
异步功能!
正在等待...
ConsoleApplication3.exe(进程17100)以代码0退出。
当我为“ x86”编译并运行时,我得到:
正在等待...
异步功能!
然后是访问冲突,在这里:
if (WaitForSingleObjectEx(param, INFINITE, TRUE) == WAIT_OBJECT_0)
在ConsoleApplication3.exe中的0x776227FB(ntdll.dll)处引发的异常:0xC0000005:访问冲突读取位置0x36623194。
我在做什么错了?
完整示例:
#include "pch.h"
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
DWORD ThreadFunction(LPVOID param)
{
while (true)
{
printf("waiting...\n");
if (WaitForSingleObjectEx(param, INFINITE, TRUE) == WAIT_OBJECT_0)
break;
}
ExitThread(0);
return 0;
}
void AsyncFunction(UINT_PTR param)
{
printf("async function!\n");
}
int main()
{
HANDLE hThread, hStopEvent;
DWORD threadID;
hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFunction, hStopEvent, 0, &threadID);
Sleep(1000);
QueueUserAPC((PAPCFUNC) AsyncFunction, hThread, NULL);
Sleep(1000);
QueueUserAPC((PAPCFUNC) AsyncFunction, hThread, NULL);
Sleep(1000);
SetEvent(hStopEvent);
WaitForSingleObject(hThread, INFINITE);
}
答案 0 :(得分:2)
我的AsyncFunction
定义有两个错误:
1-参数类型应为ULONG_PTR
,而不是 UINT_PTR
。这实际上是我实际实施中的复制粘贴错误
2-函数缺少调用约定
void AsyncFunction(UINT_PTR param)
应该是void CALLBACK AsyncFunction(ULONG_PTR param)
然后就无需在此处强制转换为PAPCFUNC
:
QueueUserAPC((PAPCFUNC) AsyncFunction, hThread, NULL);