首頁 > 後端開發 > C++ > 主體

為什麼在 C 中使用條件變數檢查空隊列時會出現段錯誤?

Linda Hamilton
發布: 2024-10-31 21:14:29
原創
654 人瀏覽過

Why Am I Getting Segfaults When Using a Condition Variable to Check for an Empty Queue in C  ?

C 11 執行緒安全佇列:條件變數使用的混亂

在您的程式碼中,您使用互斥鎖實作了執行緒安全隊列和一個條件變數。但是,您在條件變數控制的程式碼區塊中偶爾會遇到段錯誤。具體來說,您注意到當佇列為空時會發生段錯誤,這似乎違反直覺,因為條件變數旨在表示佇列中新項目的可用性。

條件變數用法不正確

您的誤解源自於條件變數的錯誤使用。條件變數的目的是發出共享狀態變更的訊號,然後其他執行緒可以對此變更做出反應。但是,在您的程式碼中,您使用條件變數來等待特定條件(佇列為空)變為 false。這是不正確的,因為當條件變成假(即佇列不再為空)時,執行緒將喚醒,但不能保證條件保持為假(即佇列可能同時再次變空) .

正確的條件變數用法

使用條件變數的正確方法是有一個循環來檢查條件(在本例中,隊列是否為空),如果條件不滿足則進入等待狀態。當條件發出信號時,執行緒將喚醒,但它會在繼續之前立即重新檢查條件。這確保了執行緒僅在喚醒時條件仍然為真時才執行所需的操作。

替代實作

這裡是執行緒安全的替代實作解決問題的佇列:

<code class="cpp">template <class T>
class SafeQueue {
public:
  SafeQueue() : q(), m(), cv() {}

  void enqueue(T t) {
    std::lock_guard<std::mutex> lock(m);
    q.push(t);
    cv.notify_one();
  }

  T dequeue() {
    std::unique_lock<std::mutex> lock(m);
    while (q.empty()) cv.wait(lock);
    T val = q.front();
    q.pop();
    return val;
  }

private:
  std::queue<T> q;
  mutable std::mutex m;
  std::condition_variable cv;
};</code>
登入後複製

在此實作中,正確使用條件變數來等待隊列為空(或對於入隊方法為非空)的條件變為false。如果喚醒後佇列非空,執行緒只會執行所需的操作(使項目出列)。

以上是為什麼在 C 中使用條件變數檢查空隊列時會出現段錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!