【问题标题】:Can WaitForSingleEvent wait for a event to be reset ?WaitForSingleEvent 可以等待事件被重置吗?
【发布时间】:2014-07-21 06:04:26
【问题描述】:

我正在尝试编写一个线程主体(例如myThread),它使用手动重置事件与父线程同步,例如g_myThreadEvent

myThread 使用此事件通知父级它已成功检索输入参数。

我想知道父级是否可以重用相同的事件来指示myThread 退出。

下面几行:

孩子:

g_myThreadEvent = UNSIGNALLED.
myThread() {
    read_inparam()
    set(g_myThreadEvent);
    for(;;) {
       // do something important
       if(is_reset(g_myThreadEvent)) break;
    }
}

家长:

start_thread(){
    CreateThread(myThread, some_arguments);
    WaitForSingleobject(g_myThreadEvent, INFINITE);
}

stop_thread() {
    reset(g_myThreadEvent);
}

这将使我能够使用单个事件来同步线程,而不是使用单独的事件来停止线程的更简单的解决方案。

【问题讨论】:

    标签: c windows multithreading events


    【解决方案1】:

    事件没有“正在重置”状态。然而,它们确实有一个 is-set 状态(以及与之相反的,is-not-set)。清晰度无法承受(使用单独的事件会更清楚),当事件不再发出信号时,您的子线程可能会简单地中断:

    // in child-infinite-loop. break if event no longer signaled
    if (WaitForSingleObject(g_myThreadEvent, 0) != WAIT_OBJECT_0)
        break;
    

    并且父线程可以通过在子进程终止时重置事件来控制这一点。一个合适的启动应该是这样的:

    // startup the child thread
    g_myThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    g_hChildThread = CreateThread(....);
    WaitForSingleObject(g_myThreadEvent, INFINITE);
    

    正确的关机是:

    // signal a shutdown to the running child.
    ResetEvent(g_myThreadEvent);
    WaitForSingleObject(g_hChildThread, INFINITE);
    CloseHandle(g_hChildThread);
    

    重要的是,您的父母应该通过重置事件等待子线程句柄上的正确关闭信号来确保孩子完成。关闭竞争条件是由于没有密切注意这一点而产生的。

    最后,请注意,这仅适用于每个事件句柄一个子线程,如果它不适合您的特定需求,这是一个最不方便的限制。

    祝你好运。

    【讨论】:

    • 如果我从子线程设置 g_myThreadEvent 并在进入处理循环之前立即重置它会发生什么?我假设在设置 g_myThreadEvent 时应该通知父母。 (然后我应该能够等待从我的子线程设置 g_myThreadEvent)
    • @s_b 您描述的活动是 PulseEvent 旨在执行的操作。它释放 active 服务员。但是,并不能保证父母在孩子启动脉搏时正在积极等待。它具有自然的竞争条件。父进程可以启动子线程,该线程在脉冲之后运行(没有父进程等待),然后子进程进入循环检查事件信号,然后父进程最终运行,等待相同的事件信号,但现在有没有人发出信号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 2013-10-30
    • 2017-09-30
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多