条件变量替代(Windows XP上的c / c ++)

时间:2011-06-11 13:51:08

标签: winapi synchronization

我想编写一个从无限大小的任务容器中运行任务的线程。

当任务列表为空时,应该阻止尝试获取任务的线程。

来自Linux我希望使用条件变量,它将在任务添加时发出信号,并在列表为空时等待。

我发现CONDITION_VARIABLE仅适用于Windows Vista,所以这是不可能的。 由于无限大小的限制,信号量也存在问题。

有没有适当的替代品?

由于

4 个答案:

答案 0 :(得分:1)

为什么你说信号量存在问题? Linux / Windows都有信号量,其最大数量可以被实际描述为“无限制”。

在Windows上使用James的建议 - 它会正常工作。在里面。你的信号量为零。将任务添加到您的大(线程安全)容器,然后发信号通知信号量。在线程中,等待信号量,然后从容器中获取任务并处理它。如果愿意,您可以将信号量实例传递给多个线程 - 这也可以正常工作。

RGDS, 马丁

答案 1 :(得分:1)

听起来你想要一个Win32内核事件。请参阅CreateEvent

答案 2 :(得分:0)

WaitForSingleObject和CreateSemaphore?

答案 3 :(得分:0)

谢谢大家, 这就是我的结论:

void ThreadPool::ThreadStartPoint(ThreadPool* tp)
{
    while (1)
    {    
        WaitForSingleObject(tp->m_taskCountSemaphore,INFINITE); // while (num of tasks==0) block; decreament num of tasks

        BaseTask* current_task = 0;

        // get top priority task
        EnterCriticalSection (&tp->m_mutex);
        {   
            current_task = tp->m_tasksQue.top();
            tp->m_tasksQue.pop();
        }
        LeaveCriticalSection (&tp->m_mutex);

        current_task->operator()(); // this is not critical section
        current_task->PostExec();
    }
}

void ThreadPool::AddTask(BaseTask& _task)
{
    EnterCriticalSection (&m_mutex);
    {
        m_tasksQue.push(&_task);
        _task.PrepareTask(m_mutex);
    }
    LeaveCriticalSection (&m_mutex);

    if (!ReleaseSemaphore(m_taskCountSemaphore,
                          1,    // increament num of tasks by 1
                          NULL  // don't store previuos num of tasks value
                          )) 
    {//if failed
        throw ("semaphore release failed");
    }
}