文章插图
生产者生产速度快,导致一上来生产者就把队列塞满了任务,接着唤醒消费者来消费,然后挂起等待 。紧接着消费者处理完一个任务就唤醒生产者来生产,生产者生产了一个任务就喊消费者来消费,然后继续挂起 。可以看出的是,在这种情况下,队列长时间是满的,生产者大部分时间是挂起等待的 。生产者和消费者开始一小部分时间内步调是不一致的,生产者生产完,消费者才消费是串行的,但是过了一会,二者步调就变得一致了,且速度是随消费者的
3.生产者慢,消费者快
文章插图
生产者的速度慢,生产者生产一个任务立马唤醒消费者,消费者处理完一个数据,发现队列为空,然后挂起等待,接着生产者继续生产一个任务,然后唤醒消费者 。可以看出的是,队列大部分时间是为空的,消费者大部分时间是处于挂起等待的,二者步调一直是一致的,且执行速度是随生产者的,也是并行的
多生产者和多消费者模型分析做到几点:
- 生产者之间需要互斥,也就是生产者和生产者之间需要组内竞争一把锁,消费者也是如此
- 生产者和消费者之间用互斥量和条件变量做到同步和互斥(上面就做到了)
#define P_COUNT 3#define C_COUNT 3BlockQueue<Task>* q;pthread_mutex_t c_lock;// 消费者的锁pthread_mutex_t p_lock;// 生产者的锁void* Consumer(void* arg){long id = (long)arg;while (1){pthread_mutex_lock(&c_lock);// 消费(取)数据Task t(0, 0);q->ConsumeData(t);cout << "consumer " << id << " consumes a task: " << t.GetA() << " + " << t.GetB() << " = " << t.Run() << endl;pthread_mutex_unlock(&c_lock);sleep(1);}}void* Productor(void* arg){long id = (long)arg;while (1){pthread_mutex_lock(&p_lock);// 生产(放)数据int x = rand()%10 + 1;int y = rand()%10 + 1;Task t(x, y);cout << "productor " << id << " produncs a task: " << x << " + " << y << " = ?" << endl;q->ProductData(t);pthread_mutex_unlock(&p_lock);sleep(1);}}int main(){srand((size_t)time(nullptr));pthread_mutex_init(&c_lock, nullptr);pthread_mutex_init(&p_lock, nullptr);// 创建一个交易场所q =new BlockQueue<Task>;pthread_t p[P_COUNT];pthread_t c[C_COUNT];for (long i = 0; i < P_COUNT; ++i){pthread_create(p+i, nullptr, Productor, (void*)(i+1));}for (long i = 0; i < C_COUNT; ++i){pthread_create(c+i, nullptr, Consumer, (void*)(i+1));}for (int i = 0; i < C_COUNT; ++i){pthread_join(c[i], nullptr);}for (int i = 0; i < P_COUNT; ++i){pthread_join(p[i], nullptr);}pthread_mutex_destroy(&c_lock);pthread_mutex_destroy(&p_lock);delete q;return 0;}
注意:- 生产者之间需要一个互斥量,消费者之间也需要一个互斥量
- 生产者和消费者的个数可以自己调整宏变量
文章插图
POSIX信号量介绍POSIX信号量: 该信号量允许进程和线程同步对共享资源的访问 。同时也可以用于实现线程间同步 。
总结几点:
- 是什么? 信号量本质是一个计数器,描述临界资源的有效个数 。申请一个资源就对信号量减1(P操作),释放一个资源就对信号量加1(V操作)
- 为什么? 临界资源可以看成很多份,互相不冲突且高效
- 怎么用? 可以使用信号量的相关接口,来申请信号量和释放信号量(下面详细介绍)
semaphore.h
的头文件中 。信号量是一个类型为
经验总结扩展阅读
- 2023年西安7月份气温多少度 西安7月份适合旅游吗
- 迪士尼可以带饭团进去吃吗 上海迪士尼可以带三明治进去吗
- 椰汁喝了有什么好处 椰汁喝了会长胖吗
- 红烧肉吃多了会头晕吗 吃了太多肉会有什么影响
- 2023年6月21日夏至,夏至三庚入头伏,23年入伏时间确定
- 2022年农历腊月二十三是装修最佳吉日吗
- 2023年四川成都五险一金缴费标准一览表 2023年四川成都五险一金每月多少钱
- 2023年农历正月初三是不是装修的好日子
- 社保如何查询交多久查看自己的社保缴纳方法看这里!
- 上海社保缴费标准2023 上海个人社保需要交多少钱