线程安全队列 c++
ThreadSafe Queue c++
我正在尝试在std::mutex
和std::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
的文档。您的使用方式比必要的更复杂。 - 简历的使用也很奇怪:通常,你用它来通知服务员有变化。您在似乎只查询某些状态的函数中无条件地发出信号。
相关文章:
- boost::进程间消息队列引发错误
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- Android NDK传感器向事件队列报告奇怪的间隔
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 使用2个键的cpp-stl::优先级队列排序不正确
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 在一个读写器队列中,我可以用volatile替换原子吗
- 为什么我的多线程作业队列崩溃
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 使用"Task"函数指针队列定义作业管理器
- 在c++队列中使用pop和visit实现线程安全
- 为什么我需要C++中不同的排序格式来对这个USACO代码上的数组和优先级队列进行排序
- 打印优先级队列
- 共享队列的线程安全
- 带自定义比较器的最小优先级队列
- 在 Vulkan Qt 中获取队列系列
- 堆栈和队列是否像C++中的数组一样传递?
- 在C++中创建队列 - 什么是 malloc 错误?
- 优先级队列自定义比较器