在线程中等待我该怎么办?

gcum 发布于 2019-11-10 c++ 最后更新 2019-11-10 12:11 1125 浏览

我有一个主程序创建N个子线程的集合来执行一些计算。从创建线程到完成时刻,每个子元素都将完全占用他们的任务。主程序也会创建一个特殊的(N + 1)线程,它有一些间歇性的任务要执行。当某些条件满足时(如全局变量具有特定值),特殊线程将执行计算,然后返回等待这些条件再次满足。当第N + 1线程无关时,至关重要的是,它不应该减慢其他处理器的速度。 有人可以建议如何实现这一点。 编辑: 显而易见的方式是这样的:

// inside one of the standard worker child threads...
if (time_for_one_of_those_intermittent_calculations_to_be_done())
{
    global_flag_set = TRUE;
}
// inside the special (N+1)th thread
for(;;)
{
    if (global_flag_set == TRUE)
    {
        perform_big_calculation();
        global_flag_set = FALSE;
    }
    // sleep for a while?
}
已邀请:

tsint

赞同来自:

内容太长未翻译

peum

赞同来自:

是。使用条件变量。如果您在条件变量上休眠,则线程将从runqueue中删除,直到已通知条件变量。

tet

赞同来自:

您应该检查Windows API中的WaitForSingleObject和WaitForMultipleObjects函数。 WaitForMultipleObjects

psed

赞同来自:

WIN32的即用型条件类;)

class Condition {
private:
    HANDLE m_condition;
    Condition( const Condition& ) {} // non-copyable
public:
    Condition() {
        m_condition = CreateEvent( NULL, TRUE, FALSE, NULL );
    }
    ~Condition() {
        CloseHandle( m_condition );
    }
    void Wait() {
        WaitForSingleObject( m_condition, INFINITE );
        ResetEvent( m_condition );
    }
    bool Wait( uint32 ms ) {
        DWORD result = WaitForSingleObject( m_condition, (DWORD)ms );
        ResetEvent( m_condition );
        return result == WAIT_OBJECT_0;
    }
    void Signal() {
        SetEvent( m_condition );
    }
};
用法:
// inside one of the standard worker child threads...
if( time_for_one_of_those_intermittent_calculations_to_be_done() ) {
    global_flag_set = TRUE;
    condition.Signal();
}
// inside the special (N+1)th thread
for(;;) {
    if( global_flag_set==FALSE ) {
        condition.Wait(); // sends thread to sleep, until signalled
    }
    if (global_flag_set == TRUE) {
        perform_big_calculation();
        global_flag_set = FALSE;
    }
}
注意:您必须在global_flag_set周围添加锁(例如关键部分)。而且在大多数情况下,标志应该用队列或至少一个计数器替换(线程可以在“特殊”线程执行其计算时多次发出信号)。

tvel

赞同来自:

由于缺少已经给出的更优选的选项,我通常只是在循环中产生CPU,直到满足所需的条件。

qullam

赞同来自:

基本上,你有N + 1个线程的两种可能性。

  • 如果它的工作很少,最好的办法就是让它睡觉,然后根据需要将其唤醒。罕见的上下文切换是微不足道的。
  • 如果它必须经常工作,那么你可能需要自动锁定它,即一个繁忙的等待状态,以防止它被重新安排或切换。

dab

赞同来自:

您应该为此使用Windows同步事件,因此您的线程在等待时无所事事。有关详细信息,请参阅MSDN;我将从CreateEvent()开始,然后转到OpenEvent()PulseEvent()SetEvent()ResetEvent()的其他事件相关函数here。 当然,还有WaitForSingleObject()WaitForMultipleObjects(),正如mrduclaw在下面的评论中指出的那样。