运用条件变量实现生产者和消费者模型

目录

条件变量简述

线程创建

生产者和消费者模型

​编辑

消费者角度

生产者角度

多次数循环即消费者补充


条件变量简述

条件变量需要配合互斥锁进行使用,单一的互斥锁只有上锁和解锁两种,在使用时候可能会有更细致的需求。而条件变量的产生可以在某一线程的环境变量发生改变以后另一线程得到信号后作出相应的动作。

线程创建

需要的头文件

线程创建需要的函数比较简单,但在使用的时候要养成检查返回值的好习惯。因为重点在条件变量,线程创建就简单一点了。

简单的模型创建。

生产者和消费者模型

消费者角度

创建条件变量和定义一个简单的结构体吧。用于生产者的生产和消费者使用。

我在这里定义了一个链表的结点。和用于指向头结点的指针。

对于消费者来说,在刚开始要创建锁。可以先来看锁的初始化函数。

pthread_mutex_init;

互斥锁的本质是结构体,但在初学阶段暂时不着急深究,可以看做一个整数。这样在后续信号量实现生产者消费者时候会更好理解。

参数1 可以传入一个 pthread_mutex_t类型变量的地址,而参数2表示的是属性,大多数填写NULL

而在初始化的阶段,在man page中我们可以发现还有更简单的方法。

在man函数库中提供了宏进行初始化,可以省去很多功夫。

对于锁的创建和初始化我们设置为全局变量。

两种方法都在图中。

创建和初始化锁之后,就可以加锁了。

pthread_mutex_lock(&mutex); 很简单的函数,在加锁时候要避免重复加锁以免产生死锁。

加锁之后我们便可对条件进行判断了。

pthread_cond_wait这个函数,一个函数会起到三层的作用,首先呢他会阻塞等待条件变量,在等到条件合适了之后呢,这个函数会先将我们之前上的锁解开,然后进行操作,比如对公共区域生产的东西进行消耗,之后还会再加上锁。所以在最后我们还是要进行解锁。不能忘记解锁。

在consume下面我们进行数据的消化。因为我们定义的是链表结点。

可以这样表示对数据的消化,然后读取数据的话不进行修改放在解锁后也可以的。

生产者角度

对于生产者来说,在生产者诞生开始就要进行数据的生产,但是要记得在数据的传输前要进行加锁处理。

在数据传输之后要进行解锁操作,解锁后通知其他线程来消费生产的产品。

多次数循环即消费者补充

因为在使用中肯定不是单次使用,因此在生产者和消费者的函数中都加上while循环。

而且在拥有多个消费者的时候,当一个消费者已经持有锁的时候,另一个消费者在判断公共区域为空的时候,会阻塞等待锁的释放。然而如果此时公共区域还是为空的话会导致程序错误,因此在条件变量阻塞的时候应该多次循环判断公共区域是否为空。

将消费者函数中的if条件语句改为while即可。还要记得在消费者函数中释放指针。malloc对应free。

在消费者和生产者中都加上while(1)循环后,可以在命令模式使用gg=GG进行自动排版。

运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值