我想编写一个从无限大小的任务容器中运行任务的线程。
当任务列表为空时,应该阻止尝试获取任务的线程。
来自Linux我希望使用条件变量,它将在任务添加时发出信号,并在列表为空时等待。
我发现CONDITION_VARIABLE仅适用于Windows Vista,所以这是不可能的。 由于无限大小的限制,信号量也存在问题。
有没有适当的替代品?
由于
答案 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");
}
}