我想編寫一個線程,從一個無限大小的任務容器中運行任務。條件變量的替代品(在Windows XP上的C/C + +)
雖然任務列表爲空,但嘗試獲取任務的線程應該被阻止。
來自Linux我想使用條件變量,它將在添加任務時發送信號,並在列表爲空時等待。
我發現CONDITION_VARIABLE只能在Windows Vista中使用,所以這是沒有問題的。 由於無限制的限制,信號量也有問題。
是否有任何適當的結構?
謝謝
我想編寫一個線程,從一個無限大小的任務容器中運行任務。條件變量的替代品(在Windows XP上的C/C + +)
雖然任務列表爲空,但嘗試獲取任務的線程應該被阻止。
來自Linux我想使用條件變量,它將在添加任務時發送信號,並在列表爲空時等待。
我發現CONDITION_VARIABLE只能在Windows Vista中使用,所以這是沒有問題的。 由於無限制的限制,信號量也有問題。
是否有任何適當的結構?
謝謝
你爲什麼說信號量有問題? Linux/Windows都有最大數量的信號量,可以被逼真地描述爲「無限」。
在Windows上使用James的建議 - 它會正常工作。在裏面。零計數的信號量。將任務添加到您的大型(線程安全)容器中,然後發出信號。在線程中,等待信號量,然後從容器獲取任務並處理它。如果您願意,您可以將信號量實例傳遞給多個線程 - 這也可以正常工作。
RGDS, 馬丁
我想將是最好的解決方案,我想要真正的無限制,而不僅僅是「真正的」。使用這個解決方案,我不得不改變設計一點,以防止嵌套的風險。使用條件變量我可以避免... – lkanab 2011-06-12 17:10:26
'真正的無限制'是不現實的
WaitForSingleObject和CreateSemaphore?
或者如果你有多個合作伙伴,請看WaitForMultipleObjectSex。 – 2011-06-11 14:07:22
我承諾,要使用WaitFormMultipleObjectSex,我必須處於可警戒狀態,但我已經有太多的啤酒:( – 2011-06-11 14:11:38
@JohnZwinck hehe ...你改變了大寫的目的...沒有你嗎? – chacham15 2013-02-17 07:07:12
聽起來像是你想要一個Win32內核事件。見CreateEvent
。
感謝所有, 這就是我的結論是:
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");
}
}
你不需要無限計數一個信號量來做到這一點,你只需要信號隊列的轉移爲空或不和互斥/臨界區保護數據結構 – nos 2011-06-11 14:14:03
與linux不同,Windows不支持無限大容器。它也沒有足夠大的數據類型來計算無限數量的項目。你將不得不解決更實際的問題。 – 2011-06-11 17:12:01