簡體   English   中英

線程安全隊列 C++

[英]ThreadSafe Queue c++

我試圖在std::mutexstd::condition_variable的幫助下在 C++ 中創建一個線程安全隊列。代碼

#include <iostream>
#include<thread>
#include<queue>
#include<atomic>
#include<mutex>
#include<condition_variable>

using namespace std;

template<class T>
class SafeQueue{
public:
    queue<T>qu;
    mutex mut;
    condition_variable cv;
    SafeQueue(){}
    SafeQueue(queue<T>q):qu(q){}
    void push(int val){
        unique_lock<mutex>uq(mut);
        cv.wait(uq,[&](){return qu.empty();});
        qu.push(val);
        uq.unlock();
    }
    bool isEmpty(){
//      unique_lock<mutex>uq(mut);
//      uq.unlock();
        cv.notify_all();
        return qu.empty();
    }
};
void inc(SafeQueue<int>& sq){
    for(int i=0;i<10;i++)
        continue;
    if(sq.isEmpty())
        sq.push(1);
}
void inc1(SafeQueue<int>& sq){
    for(int i=0;i<10;i++)
        continue;
    if(sq.isEmpty())
        sq.push(2);
}

int main(){
    queue<int>qu;
    SafeQueue<int> sq(qu);
    thread t1(inc,ref(sq));
    thread t2(inc1,ref(sq));
    t1.join();
    t2.join();
    cout<<sq.qu.front();
}

線程安全隊列應該在最后輸出1 ,但輸出是隨機的12 ,這意味着它不是線程安全的。為什么這個特定程序不起作用?

並不意味着程序不是線程安全的。 這並不意味着它定義不明確並且可能會崩潰。

這只是意味着您的程序邏輯不會以任何特定順序將項目添加到隊列中。

如果您希望以特定順序添加這兩個項目,請從一個線程推送這兩個項目。

線程安全並不意味着您的應用程序就像只有一個線程一樣運行。

你的程序運行良好。

您的代碼存在以下幾個方面的缺陷:

  • 無論何時訪問共享結構,都必須由互斥鎖保護。 您有一個互斥鎖,但您不在isEmpty()使用它。 記錄該連接,這很重要,不要迷失方向。 另外,對簡歷做同樣的事情,在收到信號時記錄下來。
  • 關於isEmpty() ,該函數無論如何都沒用。 即使隊列在某個時間點不是空的,也沒有什么可以阻止它在下一秒變空。
  • 重新閱讀unique_lock的文檔。 您使用它的方式比必要的要復雜。
  • 簡歷的使用也很奇怪:通常,你用它來通知服務員有變化。 您在一個似乎只查詢某些狀態的函數中無條件地發出信號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM