生产者消费者 & 读者写者

生气 生产者消费者

偷笑对于生产者消费者这个问题,我们可以用生活中一个简单的例子来说明:

桌子上有个盘子,一个人往盘子里面放苹果,一个人从盘子里面拿走苹果,放苹果的人相当于生产者,拿走苹果的人相当于消费者,而盘子就相当于一个生产场所。如果我们要保证拿苹果的人一直都有苹果拿,那就要让放苹果的人一直放,而且要比拿苹果的人快一点。当盘子满的时候放苹果的人就要等着拿苹果的人把苹果拿走,等盘子里有了位置,就可以继续放苹果。如果我们要求每次只能放一个苹果,拿苹果的人每次也只能拿一个苹果,而放苹果和拿苹果的人都不只是一个人,这样的话,放苹果的人和放苹果的人之间就会产生互斥关系,一个人放苹果的时候,其他人就不能放,拿苹果的人也是一样,一个人拿苹果的时候,其他人就不能拿。而拿苹果的人和放苹果的人也有互斥关系和同步关系,放苹果的人放了苹果之后,要通知拿苹果的人来拿苹果,否则盘子满了,放苹果的人就要等待。

惊恐惊恐惊恐惊恐惊恐惊恐惊恐惊恐惊恐惊恐惊恐惊恐惊恐


偷笑好了,不说苹果了,我们来官方一点啦

生产者要做的就是生产数据,消费者要做的是读取数据并且要拿走。而且生产者和消费者是在一个环形缓冲区进行的,和我在管道那篇博客中写的一样


疑问生产者消费者之间的关系

(1)消费者和消费者是互斥关系,因为一个消费者来读取数据的时候其他消费者是不能来读取数据的
(2)生产者和生产者是互斥关系,因为一个生产者在写入数据的时候其他生产者是不能写入数据的
(3)生产者和消费者是互斥关系,同步关系,当生产者生产了之后,会通知消费者来消费,否则当生产者生产满了的时候,就需要等待消费者来消费,等到满足生产的要求的时候再生产,这就对于临界资源的访问会产生一定的顺序,会提高系统内部资源的读取速度。

消费者指向的位置都是有有效数据的,生产者指向的位置都是没有有效数据的,和管道的环形缓冲区类似,把管道的环形缓冲区图拿过来凑合看看理解吧。 这幅图里面,你可以把write看作是生产者,在一直生产数据,read可以看作是消费者,一直在读取数据。 生产者所关心的资源是环形buf中空余的位置,即没有有效数据的位置, 消费者不关心格子,只关心数据



生气读者写者问题

疑问 读者写者都干什么呢?
   写者把数据扔到缓冲区中,读者只读数据,不会把数据拿走

疑问读者写者的关系:
(1)读者和读者没有关系,因为数据不会被拿走,不会发生争夺资源的问题,所以谁都可以读到相同的数据,
(2)写者和写者是互斥关系,一个写的时候其他写者就不能写
(3)读者和写者是互斥关系,同步关系,类似生产者和消费者

可怜读者写者会出现的问题:
(1)读者很多,写者只有一个的时候,读者会不断的来读数据,写者没机会写如数据,则会出现写者饥饿
(2)写者很多,读者只有一个的时候,写者会不断的写入数据,读者没机会写入数据,则会出现读者饥饿

大笑针对写者饥饿和读者饥饿的解决方法:
(1)写者优先:当有很多读者的时候,当写者来的时候,后续来的读者就不能读了,等当前正在读的读者读完,然后让写者先写,其他读者不能进行读取
(2)读者优先:当有很多写者,来了一个读者的时候,当当前写者写完的时候让读者先读,读完了再让其他的写者写

疑问关于读写锁:
(1)以只读方式加锁,是读者的行为,当有写者的时候,写者不会进行写操作,写者检测到读者有读锁的时候(Pthread_rwlock_tryrdlock(&rwlock)!=0) 会等待,直到读者不再读,如果没有检测到只读锁(Pthread_rwlock_tryrdlock(&rwlock)==0),则会直接写入
(2)其他锁是基于挂起,当申请锁的时候申请不到就会被挂起等待其他进程释放锁
(3)读写锁是基于自旋锁,申请锁资源,如果锁资源就绪,就会立即被占用,如果锁资源没有就绪,则会一直自旋申请

自旋锁:当申请资源的时候不会被挂起,节省了挂起和唤醒的代价

如果在临界资源里逗留的时间很长,则需要使用互斥锁或者信号量














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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值