在多執行緒環境中,確保程式碼的關鍵部分受到保護以防止資料損壞至關重要。其中一個關鍵部分是資料隊列的管理。佇列是一種遵循「先進先出」(FIFO) 原則的資料結構。在 C 11 中實作執行緒安全佇列涉及使用互斥體和條件變數等同步機制。
相關程式碼片段展示了使用 std::mutex 和 std::condition_variable 的執行緒安全隊列。 enqueue 方法將一個項目加入佇列中,同時持有 qMutex 上的鎖以保護佇列。它還使用 populatedNotifier 條件變數通知任何等待執行緒。
出隊方法從佇列中檢索項目。它取得 qMutex 上的唯一鎖,檢查佇列是否為空,並在必要時使用 wait_for 函數進行逾時等待。如果執行緒收到佇列中有新項目的通知,它將退出等待並繼續從佇列中檢索和刪除項目。
但是,當佇列為空時,會觀察到段錯誤,這表示 wait_for 函數傳回無需通知。這可能是由於虛假喚醒而發生的。
為了防止此問題,建議反轉 while 迴圈的條件。不要“等待隊列不為空”,而是在“隊列為空”時等待。這確保循環在任何虛假喚醒後重新檢查佇列的空性。
這是出隊方法的修訂版本:
<code class="cpp">std::string FileQueue::dequeue(const std::chrono::milliseconds& timeout) { std::unique_lock<std::mutex> lock(qMutex); while (q.empty()) { if (populatedNotifier.wait_for(lock, timeout) == std::cv_status::no_timeout) { // Lock may have been released spuriously; recheck condition if (q.empty()) { return std::string(); } std::string ret = q.front(); q.pop(); return ret; } else { return std::string(); } } std::string ret = q.front(); q.pop(); return ret; }</code>
這確保執行緒僅在以下情況下繼續進行:佇列不為空,避免了虛假喚醒所造成的段錯誤。
以上是使用 `std::condition_variable::wait_for` 時如何防止 C 11 執行緒安全佇列中出現段錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!