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中文網其他相關文章!