首頁  >  文章  >  後端開發  >  使用 `std::condition_variable::wait_for` 時如何防止 C 11 執行緒安全佇列中出現段錯誤?

使用 `std::condition_variable::wait_for` 時如何防止 C 11 執行緒安全佇列中出現段錯誤?

DDD
DDD原創
2024-11-01 11:49:30916瀏覽

How to Prevent Segfaults in a C  11 Thread-Safe Queue When Using `std::condition_variable::wait_for`?

C 11 中的執行緒安全佇列

在多執行緒環境中,確保程式碼的關鍵部分受到保護以防止資料損壞至關重要。其中一個關鍵部分是資料隊列的管理。佇列是一種遵循「先進先出」(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&amp; 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn