Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
异步过程调用 我试图用我的C++代码工作,但我失败了。我说不出话来。在C#中,它可以正常工作(逻辑上是相同的代码)。我希望线程2将调用注入线程1。但是在我的C++项目中,它不会因为某种原因而执行。我做错了什么 螺纹1(主螺纹) 线程2(子线程,需要主线程来执行函数)_C++_C_Multithreading_Winapi_Asynchronous - Fatal编程技术网

异步过程调用 我试图用我的C++代码工作,但我失败了。我说不出话来。在C#中,它可以正常工作(逻辑上是相同的代码)。我希望线程2将调用注入线程1。但是在我的C++项目中,它不会因为某种原因而执行。我做错了什么 螺纹1(主螺纹) 线程2(子线程,需要主线程来执行函数)

异步过程调用 我试图用我的C++代码工作,但我失败了。我说不出话来。在C#中,它可以正常工作(逻辑上是相同的代码)。我希望线程2将调用注入线程1。但是在我的C++项目中,它不会因为某种原因而执行。我做错了什么 螺纹1(主螺纹) 线程2(子线程,需要主线程来执行函数),c++,c,multithreading,winapi,asynchronous,C++,C,Multithreading,Winapi,Asynchronous,代码: #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, GetCurrentThread


代码:

#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;
}
这就是你的问题陈述。APC非常危险,它们允许代码重入。这个粗糙的语句相当于臭名昭著的Application.DoEvents()语句,它让很多VB程序员陷入了麻烦。Windows不仅让它们运行,还必须明确代码是可重入的,这样APC就可以安全运行,而不会破坏程序状态

具体要求是线程处于“可警报等待状态”。进入等待状态不是问题所在,Sleep()调用可以做到这一点。但是,它不是一个可警报状态。您必须使用此选项:

  SleepEx(TIME, TRUE);

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

几个小时前你去过哪里?:)我从来没有想到这是一个无伤大雅的
睡眠
。我被问到:)我对你的复制代码表示敬意,希望每一个SO用户都能像你一样轻松地帮助他们。根据你的说法,没有办法让一个健康的GUI线程本身接受APC调用,对吗?我现在必须在MFC中使用它。不,阻塞UI线程只会产生一个死掉的用户界面。
  SleepEx(TIME, TRUE);