WaitForSingleObject 和事件,不明确的行为

WaitForSingleObject and Events, unclear behaviour

我用 Visual Studio 2017 在 Windows 10 64 位上写了两个小测试应用程序,我想用它来测试事件和 WaitForSingleObject。

我也在使用 intervalzero 的 RTX 实时扩展。

我的一个应用程序是用 x64 代码编写的 windows 部分,另一个是用 x64 代码编写的 RTX 子系统。

现在我的想法是在 RTX 64 中创建一个事件并让它发出 10 次信号并在信号之间给定的暂停时间:

int _tmain(int argc, _TCHAR * argv[])
{

    RtPrintf("Starte RTX-Applikation\n");
    RtSleep(0);
    HANDLE hEvent = RtCreateEvent(NULL, false, false, _T("flexLZSStart"));
    if (hEvent != INVALID_HANDLE_VALUE)
    {
        RtPrintf("Event erzeugt\n");
        for (size_t i = 0; i < 10 ; i++)
        {
                RtSetEvent(hEvent);
                RtPrintf("Event gesetzt\n");
                RtSleep(1500);
        }
        RtCloseHandle(hEvent);
    }

    RtPrintf("exit process\n");
    return 0;
}

另一方面,windows 应用程序检查事件的创建,然后重复检查事件是否已发出信号:

int main()
{
    Sleep(150);
    HANDLE hEvent = NULL;
    DWORD dwstart = GetTickCount();
    printf("wait for creation of event\n");
    while (hEvent == NULL)
    {
        hEvent = RtOpenEvent(NULL, NULL, _T("flexLZSStart"));
    }
    if ((hEvent == INVALID_HANDLE_VALUE) || (hEvent == NULL))
    {
        exit(-2);
    }
//#define REOPEN
    if ((hEvent != INVALID_HANDLE_VALUE) && (hEvent != NULL))
    {
        DWORD dwErg;
        BOOLEAN aborted = false;
        printf("Event has been created.\n");
#ifdef REOPEN
        RtCloseHandle(hEvent);
#endif
        do
        {
            printf("Wait for event to be signaled\n");
#ifdef REOPEN
            hEvent = RtOpenEvent(NULL, NULL, _T("flexLZSStart"));
            if (hEvent == NULL)
            {
                printf("Event has been disposed?\n");
                break;
            }
#endif
            dwErg = RtWaitForSingleObject(hEvent,1000);
#ifdef REOPEN
            RtCloseHandle(hEvent);
#endif
            DWORD dwLastError = GetLastError();
            if (dwLastError != 0)
            {
                printf("GetLastError returned %d!\n", dwLastError);
            }
            switch (dwErg)
            {
            case WAIT_OBJECT_0:
                printf("received Event\n");
                RtResetEvent(hEvent);
                break;
            case WAIT_TIMEOUT:
                //printf("event not yet received\n");
                break;
            case WAIT_ABANDONED:
            {
                printf("owner of event has been killed\n");
                aborted = true;
            }
            break;
            default:
            {
                printf("no valid return value: %d\n", dwErg);
                aborted = true;
            }
            break;
            }
        } while (!aborted);

    }
    printf("loop exited\n");
    exit(0);
}

现在我的观察是,RTX 代码运行正常,并在发出 10 次事件信号后退出。

另一方面,windows 代码接收事件 10 次,但它没有检测到 rtx 应用程序何时关闭事件。

如果我使用定义的 REOPEN 编译代码,windows 代码会随着事件的 11.open 退出,因为它不再可用。

我应该通过有第二个事件来增强我的代码,该事件由 windows 代码在收到第一个事件后触发,以便 rtx 代码等待 windows 代码完成它的工作。

但我的最后一个问题是:

检测事件源是否仍然有效的正确方法是什么?

我可以检测到 rtx 代码已经创建了事件,但在它最终退出之前还没有发出信号吗?

由于我对两个应用程序的编程方式,无法检测到 sender 已结束。

为了检测到这一点,我应该实现另一个互斥体,当 sender 退出时被触发。所以 接收者 可以检测到信号互斥锁并自己退出。