线程安全队列 c++

ThreadSafe Queue c++

本文关键字:c++ 队列 安全 线程      更新时间:2023-10-16

我正在尝试在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,但输出是随机的,要么是1的,要么是2的,这意味着它不是线程安全的。为什么这个特定的程序不起作用?

这并不意味着程序不是线程安全的。这并不意味着它定义不明确,可能会崩溃。

这只是意味着程序的逻辑不是为了以任何特定顺序将项目添加到队列中而编写的。

如果要按特定顺序添加这两个项目,请从一个线程推送这两个项目。

线程安全并不意味着您的应用程序像只有一个线程一样运行。

您的程序运行正常。

您的代码在几个方面存在缺陷:

  • 每当您访问共享结构时,都必须由互斥锁保护。您有互斥锁,但不在isEmpty()中使用它。记录该连接,这很重要,不要丢失跟踪。此外,对简历执行相同的操作,在发出信号时记录。
  • 关于isEmpty(),这个函数无论如何都是无用的。即使队列在某个时间点不为空,也没有什么可以阻止它在下一秒变为空。
  • 重新阅读unique_lock的文档。您的使用方式比必要的更复杂。
  • 简历的使用也很奇怪:通常,你用它来通知服务员有变化。您在似乎只查询某些状态的函数中无条件地发出信号。