#include<iostream>
#include<thread>
#include<vector>
#include<list>
#include<mutex>
#include<chrono>
#include<random>
#include<stdio.h>
using namespace std;
class test
{
private:
mutex mut;
list<int> li; //任务队列
default_random_engine e; //生成随机无符号数
condition_variable cond; //条件变量
test() {}; //单例模式
public:
//单例模式
static test& Instance()
{
static test t;
return t;
}
~test()
{
cout << "~test" << endl;
}
//生产者
void product()
{
uniform_int_distribution<unsigned> u(1, 10); //生成1到10(包含)均匀分布的随机数
for (int i = 0; i < 1000000; i++)
{
this_thread::sleep_for(chrono::milliseconds(u(e))); //每隔一个随机ms时间,生产者进行生产
lock_guard<mutex> lg(mut);
cout << "product --- " << i << endl;
li.push_back(i);
cond.notify_all(); //唤醒等待的消费者
}
}
//消费者
void consume(int id)
{
uniform_int_distribution<unsigned> u(10, 100); //生成10到100(包含)均匀分布的随机数
while (1)
{
unique_lock<mutex> ul(mut, try_to_lock); //try_to_lock表示尝试加锁
if (ul.owns_lock()) //成功拿到锁
{
cond.wait(ul, [this]()->bool { //!li.empty()为真表示队列中有值,可以消费,
return !li.empty(); //如果队列中没有值,则ul释放锁资源并等待notify_all唤醒
}); //唤醒后继续判断!li.empty(),为真的话重新上锁继续下面程序,否则继续等待唤醒
printf("consume_id<%d> -- %d\n", id, li.front());
li.pop_front();
}
else //如果没有拿到锁,可以执行其他操作,不必阻塞,更加灵活
{
//其他操作
this_thread::sleep_for(chrono::milliseconds(1)); //没拿到锁就等1ms再尝试
continue;
}
ul.unlock();
this_thread::sleep_for(chrono::milliseconds(u(e))); //每隔一个随机ms时间,消费者进行消费
}
}
};
int main()
{
test* a = &test::Instance();
thread t1(&test::product, a); //a作为this指针传入
for (int i = 1; i <= 10; i++) //十个消费者
{
thread t2(&test::consume, a, i);
t2.detach();
}
t1.join();
return 0;
}
测试结果: