gpt4 book ai didi

c++ - 异步过程调用

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:18:49 25 4
gpt4 key购买 nike

我正在尝试获取 APC在我的 C++ 代码中工作,但我失败了。我不知所措。在 C# 中它工作得很好(逻辑上相同的代码)。我希望线程 2 向线程 1 注入(inject)一个调用。但在我的 C++ 项目中,由于某种原因它不会执行。我做错了什么?

  • 线程 1(主线程)
  • 线程2(子线程,需要主线程执行一个函数)


代码:

#include "stdio.h"
#include "windows.h"

#define TIME 2500
#define LAST_ERROR printf("last error: %i\r\n", GetLastError());

HANDLE handle1, handle2;

void ThreadInfo(char* prefix = "")
{
printf("%sthread id: %i\r\n", prefix, GetCurrentThreadId());
}

VOID CALLBACK apc( _In_ ULONG_PTR data)
{
ThreadInfo(" -> apc: 2 -> 1: ");
}

void run1()
{
while (true)
{
Sleep(TIME);
ThreadInfo("1: ");

// apc
//QueueUserAPC(apc, handle2, (ULONG_PTR) NULL);
}
}

void run2()
{
while (true)
{
Sleep(TIME);
ThreadInfo("2: ");

// apc
QueueUserAPC(apc, handle1, (ULONG_PTR) NULL);
}
}

void TestThreads()
{
DWORD threadId;
SECURITY_ATTRIBUTES a;
a.nLength = 12;
a.lpSecurityDescriptor = NULL;
a.bInheritHandle = 1;

DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &handle1, 0, true, 2);
LAST_ERROR

handle2 = CreateThread(NULL, 100000, (LPTHREAD_START_ROUTINE)run2, NULL, 0, &threadId);
printf("handles (1, 2): %i, %i\r\n", handle1, handle2);
printf("ids (1, 2): %i, %i\r\n", threadId, GetCurrentThreadId());
printf("--------------------------------\r\n");
run1();
}

int main()
{
TestThreads();

printf("done.");
getchar();
return 0;
}

最佳答案

  Sleep(TIME);

这就是你的问题陈述。 APC 非常危险,它们允许代码重入。大致等同于臭名昭著的 Application.DoEvents() 语句,它让许多 VB 程序员陷入困境。 Windows 不仅仅让它们运行,您必须明确您的代码是可重入的,这样 APC 才能安全运行而不会搞砸您的程序状态。

具体要求是你的线程处于“alertable wait state”。进入等待状态不是问题,Sleep() 调用可以做到这一点。然而,它不是一个可警告的状态。你必须改用它:

  SleepEx(TIME, TRUE);

修改测试程序中的 run1() 函数,您现在将看到调用 APC 回调。与 GetOverlappedResultEx()、SignalObjectAndWait()、WaitForSingleObjectEx() 和 WaitForMultipleObjectsEx() 相比,其他可以将线程置于可警告等待状态的 winapi 调用。是的,托管程序中的 Thread.Sleep() 是可警报的,CLR 在后台调用 SleepEx()。

关于c++ - 异步过程调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23737754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com