c++ - 异步过程调用中的 GetLastError 竞争

标签 c++ c multithreading winapi asynchronous

假设我正在使用 APC,其中过程和调用代码都使用 SetLastError 和 GetLastError。这会导致 GetLastError 产生不可预测的值。有什么办法可以解决这个问题吗?

VOID CALLBACK MyFunction(ULONG_PTR param)
{

    SetLastError(1);
    // Doing some stuff here which takes some time
    // Expecting 1 but can I/should I get 0 here ?
    printf("LastError: %d\n", GetLastError());    
}

int APCtry()
{

    SetLastError(0);

    DWORD dummy = 0;

    if (!QueueUserAPC(MyFunction, GetCurrentThread(), dummy))
    {
        return 0;
    }      

    printf("LastError: %d\n", GetLastError());

    SleepEx(100, TRUE);

    //SetLastError(0); Edited and commented

    printf("LastError: %d\n", GetLastError());

    return 0;
}

最佳答案

在 MyFunction 中,您始终应该将 1 作为 LastError。

APCtry has already gone ahead after MyFunction started doing the time consuming part...

这是一个很大的困惑:你所有的代码都在单线程中执行!

SleepEx begin...
MyFunction...
SleepEx return
SetLastError(0); in APCtry()

所以 SleepEx 在 MyFunction 完成之前不会返回。所以你在 SleepEx 之后设置为最后一个错误(或设置 SleepEx 的内容)- 对 MyFunction 没有任何影响- 因为这一切只会在 MyFunction 之后发生导出。您在 MyFunction 中设置为最后一个错误的内容- 这是你必须到达这里的地方

编辑

为了更清楚地了解 SleepEx 内部发生了什么: enter image description here

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

相关文章:

c++ - opencv中ocl模块的使用方法

c++ - 从 int 到 c 字符串 (const char*) 的转换失败

通过改变宏的值进行条件编译

java - 如何使用ExecutorService批量运行任务

android - 如果我的 Android 应用程序没有 UI,我应该在单独的线程中工作吗?

c++ - 指向移位数组 C++ 的指针

c++ - 管理进程如何在登录用户中打开应用程序?

c - "int *a = (int[2]){0, 2};"究竟是做什么的?

c - __align(A) 在 C 中是什么意思

java - 将 Integer 对象用作同步块(synchronized block)中的锁时的潜在并发问题