我想做的事
嗨,我有兩種型別的執行緒,主執行緒和作業執行緒等于 CPU 上的內核數的作業執行緒,我想要做的是當主執行緒需要呼叫更新時我設定了一個布林值呼叫更新為 true 并呼叫,condition_variable(cv).notify_all然后每個執行緒將執行其作業,完成后它將增加一個atomic_int呼叫 CoresCompleted 后跟 acv.notify_all以便主執行緒可以檢查所有作業是否已完成,然后它將等待變數 Updating 為 false因此可以確定所有其他執行緒都已完成并且它不會再次更新,一旦一切完成,主執行緒將更新設定為 false 并通知所有人。
代碼
主要的
void UpdateManager::Update() {
//Prepare Update
CoresCompleted = 0;
Updating = true;
//Notify Update Started
cv.notify_all();
//Wait for Update to end
auto Pre = high_resolution_clock::now();
cv.wait(lk, [] { return (int)UpdateManager::CoresCompleted >= (int)UpdateManager::ProcessorCount; });
auto Now = high_resolution_clock::now();
auto UpdateTime = duration_cast<nanoseconds>(Now - Pre);
//End Update and nofity threads
Updating = false;
cv.notify_all();
}
作業人員
void CoreGroup::Work() {
Working = true;
unique_lock<mutex> lk(UpdateManager::m);
while (Working) {
//Wait For Update To Start
UpdateManager::cv.wait(lk, []{ return UpdateManager::Updating; });
if (!Working)
return;
//Do Work
size_t Size = Groups.size();
auto Pre = high_resolution_clock::now();
for (size_t Index = 0; Index < Size; Index )
Groups[Index]->Update();
auto Now = high_resolution_clock::now();
UpdateTime = duration_cast<nanoseconds>(Now - Pre);
//Increment CoresCompleted And Notify All
UpdateManager::CoresCompleted ;
UpdateManager::cv.notify_all();
//Wait For Update To End
UpdateManager::cv.wait(lk, []{ return !UpdateManager::Updating; });
}
}
問題
Once the workers reach the last wait where they wait for Updating to be false they get stuck and never leave, for some reason the last notify_all in the main thread is not reaching the workers, I tried searching and looked for many examples but I can't figure out why it isn't triggering, maybe I miss understood how the cv and lock works, any ideas why this is happening and how to fix?
uj5u.com熱心網友回復:
以下是您的代碼的作業方式:Update收到通知后,一些等待已結束:
cv.wait(lk, [] { return (int)UpdateManager::CoresCompleted >= (int)UpdateManager::ProcessorCount; });
它不再等待,需要對互斥鎖進行鎖定。繼續做它的事情然后到達結尾并通知其他執行緒他們可以繼續使用這一行:
cv.notify_all();
但它是謊言,他們不能繼續作業,因為你拿著鎖。釋放它,他們將繼續作業:
void UpdateManager::Update() {
<...>
//End Update and nofity threads
Updating = false;
lk.unlock();
cv.notify_all();
}
這可能不是這段代碼中唯一的問題,但我假設您在進入Update方法之前鎖定了互斥鎖,或者有一些保證它在另一個之前運行(Work)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/457394.html
