话不多说直接上代码。
代码里有注解。
#include<condition_variable>
#include<mutex>
#include<thread>
#include<iostream>
#include<chrono>
using namespace std;
using namespace this_thread;
//1,不安全线程队列
void insertDater(queue<int> &date,int num)
{
date.push(num);
}
void testQueue()
{
queue<int> date;
for (int i = 0; i < 10; i++)
{
thread t(insertDater, ref(date),i);
t.join(); //使用t.detach(); 存在不安全
}
this_thread::sleep_for(3s);
while (!date.empty())
{
cout <<date.front()<<" " ;
date.pop();
}
}
//2,封装一个线程安全队列
template<class T>
class thread_safe_queue
{
protected:
mutable mutex mut;
queue<T> date_queue;
condition_variable date_cond;
public:
thread_safe_queue() {}
thread_safe_queue(thread_safe_queue const& other)
{
lock_guard<mutex> lk(other.mut);
date_queue = other.date_queue;
}
void push(T new_value)
{
lock_guard<mutex> lk(mut);
date_queue.push(new_value);
date_cond.notify_one(); //唤醒线程
}
//等态线程存储数据结束后做一个数据的出队列
void wait_and_pop(T& value)
{
unique_lock<mutex> lk(mut);
date_cond.wait(lk, [this] {return !date_queue.empty(); });
value = date_queue.front();
date_queue.pop();
}
shared_ptr<T> wait_and_pop()
{
unique_lock<mutex> lk(mut);
date_cond.wait(lk, [this] {return !date_queue.empty(); });
shared_ptr<T> res(make_shared<T>(date_queue.front()));
date_queue.pop();
return res;
}
bool empty() const
{
lock_guard<mutex> lk(mut);
return date_queue.empty();
}
};
void insertDate(thread_safe_queue<int>& date, int num)
{
date.push(num);
}
void threadSafeQueue()
{
thread_safe_queue<int> date;
for (int i = 0; i < 10; i++)
{
thread t(insertDate, ref(date), i);
t.join(); //使用t.detach(); 存在不安全
}
this_thread::sleep_for(3s);
int num = 0;
while (!date.empty())
{
date.wait_and_pop(num);
cout << num << " ";
}
}
int main()
{
//testQueue();
threadSafeQueue();
return 0;
}