2016-07-22 36 views
0

我正在設計一個系統,其中一個工作者池將任務從隊列中彈出,並且我希望主線程等待所有要完成的任務。這是我想出迄今(僞):一個線程在幾個等待的信號機制

// Main 
launch_signal(); 
for (auto &worker : pool) { 
    // create unique_lock 
    if (!worker.done) 
     worker.condition_variable.wait(lock, worker.done); 
} 

// Worker 
if (queue.empty()) { 
    mutex.lock(); 
    this->done = true; 
    mutex.unlock(); 
    this->condition_variable.notify_one(); 
    // wait for launch signal from Main 
} else { 
    mutex.lock(); 
    auto job = queue.pop(); 
    mutex.unlock(); 
    job.execute(); 
} 

所以Main信號的作業都可用,然後等待每一位勞動者的信號了。同時保持彈出作業不在隊列中直到空,然後完成信號並進入等待發射信號。

我的問題:什麼是更有效的算法呢?

+0

[OT]您應該使用['std :: lock_guard'](http://en.cppreference.com/w/cpp/thread/lock_guard),而不是手動鎖定和解鎖互斥鎖。 – NathanOliver

+0

絕對如此(重要)細節被省略。 –

回答

1

現有代碼似乎訪問queue.empty()而不持有互斥鎖。除非queue對象本身是線程安全的(或者至少將queue.empty()方法明確記錄爲線程安全的),否則這將是未定義的行爲。

所以第一個改進就是解決這個可能的錯誤。

否則,這是一個相當股票,戰鬥測試,實施一個工作人員池。這裏沒有太多的改進空間。

我可以做的唯一的建議是,如果工作線程數爲N,並鎖定一個線程發現有J工作隊列互斥後,線程可以刪除J/N職位(的結果除了至少1)從隊列中立即開始,然後按順序執行它們,假設所有其他線程都會執行相同的操作,並且平均而言,作業需要大致相同的時間才能完成。這將最小化鎖爭用。