我想通過異步 Web 請求處理程式將專案添加到一個執行緒中的佇列中:
void handleRequest(item) {
toProcess.push_back(item);
}
有一個后臺執行緒不斷地處理這些佇列項,如下所示:
while(true) {
for(auto item : toProcess) { doSomething(item); }
toProcess.clear();
}
顯然,這不是執行緒安全的……您可能會在 for 回圈完成時將一個專案添加到 toProcess 中,從而將其清除而不進行處理。撰寫這樣的程式的最佳模型是什么?
uj5u.com熱心網友回復:
我將使用std::atomic<T>::waitwhich 是一個C 20功能,但是也有一種方法可以使用條件變數來做到這一點,并且它們自C 11.
包括<atomic>和<mutex>
您將需要一個成員 atomic_bool。
std::atomic_bool RequestPassed = false;
和成員互斥鎖
std::mutex RequestHandleMutex;
你的 handleRequest 函式就會變成
void handleRequest(item) {
std::lock_guard<std::mutex> lg(RequestHandleMutex)
toProcess.push_back(item);
RequestPassed.store(true);
RequestPassed.notify_all();
}
你的回圈就是這個
while(true) {
RequestPassed.wait(false);
std::lock_guard<std::mutex> lg(RequestHandleMutex)
/* handle latest item passed */
RequestPassed.store(false);
}
這樣,while 執行緒會等待而不是不斷迭代(節省 CPU 電量和電池)。如果您隨后使用handleRequest,則 atomic_bool 會收到通知停止等待,請求被處理(互斥鎖被鎖定,因此在發生這種情況時不會有新請求到來),RequestPassed 被重置為 false,執行緒等待下一個請求。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382673.html
上一篇:多執行緒沒有阻塞方法的類
