关于通过队列解决共享资源互斥或同步问题说明

软件实现中经常会遇到共享资源的互斥或同步问题(也可以扩展到并发问题),针对不同的生产者消费者模型,我们需要选择合适的处理方法。这些模型包括单生产者单消费者、单生产者多消费者、多生产者多消费者模型,面对这些模型,我们最简单的是使用加锁机制解决,但是加锁这种方式显然牺牲了软件的处理性能,没有万不得已不推荐这种方法(比如多生产者多消费者模型)。而处理我们常见的单生产者单消费者、单生产者多消费者两种模型有没有更好的方法呢,那就是这里要讲的队列,这里说队列准不准确呢,其实也不准确,准确的来说是读写指针这种实现方式具有同步功能。本文主要针对的是我们较为常见的单生产者单消费者、单生产者多消费者两种模型进行说明。

1.关于读写指针实现互斥和同步问题说明

1.1 单生产者单消费者模型

对于单生产者单消费者模型,除了通常的加锁方式进行处理,还可以通过队列的方式实现,其实质就是依赖于队列接口是单向输入(写指针)、单向输出(读指针),本身具备同步的功能。使用队列方式的好处是可以提高任务的执行效率(不需要任务通过锁频繁切换),代码实现注意保证数据写完成后再更新写指针,数据读完毕后再更新读指针的要求即可。

例:裸机下某一个全局变量表示有效数据条数,在中断中收到有效数据对该变量进行增1操作,在主函数中判断该变量来确认数据条数,并处理数据,处理结束后对该变量进行减一操作。在这里插入图片描述

本来这样的逻辑似乎没问题,但是实际上我们要考虑到对变量执行–操作是非原子(读-改-写)的操作,相对于以下三步(读内存到寄存器;2、在寄存器更改值;3、写回内存):
1)Tmp = FLAG;
2)Tmp = Tmp-1;
3)FLAG= Tmp;
如果Flag = 1;当执行完第二步,Tmp得到0,这时中断又收到了有效数据,Flag 在中断中变成2,返回主任务执行第三步Flag 得到0,那么就导致丢失有效数据。这里的问题实际上变成了对共享资源Flag的互斥问题。解决办法:通过使用读写指针的方法:定义两个全局变量A 和B,初值两者均为0.

中断中对A变量进行++操作,而主任务中判断B是否等于A,如果不等于A,则处理有效数据,处理完数据后B++。这种A B两个变量的实质逻辑就是等同于队列中的读写指针,数据写完成后更新写指针,数据读取完成后更新读指针,通过两个指针实现同步的机制。

1.2 单生产者多消费者模型

单生产者多消费者模型,共享资源的竞争一定不要想着通过一个队列来实现,在多任务系统下仅仅一个读指针和写指针是没有办法保证资源的原子性的,因为读期间可能没完成就存在被其他高优先级读任务中断而导致数据出现不完整的问题。我们完全可以通过多个队列来实现啊,本质上是来形成多个单生产者单消费者模型,这样各个消费者之间不存在竞争关系了。我们按照实际使用中的场景分为两类:一类是消费者共享生产者资源,消费者消费一份,其他消费者可使用的生产资源就少一份;另一种是消费者拥有相同的生产者资源,一个消费者消费并不影响另一个消费者拥有的资源。

类型1:消费者共享生产者资源
比如:A任务为生产者,B、C、D任务同为消费者,B任务消费资源后,C和D的可用资源会变少.
在这种工况下,我们可以设计三个队列,A生产资源后通过队列查询B、C、D队列的可用空间将资源分配给B、C、D任务中有可用空间的队列,这样变相实现了负载均衡,依据实际B、C、D任务的处理快慢分配对应的资源。

类型2:消费者拥有相同的生产者资源
比如:A任务为生产者,B、C、D拥有相同的生产资源,设计三个队列,A生产者将资源拷贝至三个独立队列,由B、C、D分别单独处理自己的资源。

1.2 多生产者多消费者模型

对于多生产者多消费者模型,队列无法解决多生产者多消费者模型,针对该工况,仍需要具体来通过锁实现。

2.队列的另一个优点:作为缓冲区

队列除了上述读写指针实现的无锁同步特点外,经常添加队列(或者数组结构)作为发送或者接收数据的缓冲区的另外的作用就是防突发功能,另外还可以隔离硬件。
防突发功能:
比如一个网卡
接收数据,如果没有缓冲区,在裸核任务中,如果当前时刻网卡收到多包数据,那么实现只能收到一包数据进行处理,再查询下一包,再进行处理。假如处理期间来了多包以太网数据,由于处理数据慢很可能导致丢包。而有缓冲区的存在,可以接收时先将多包数据存储到缓冲区,再统一处理。这样的处理在带操作系统情况下更下明显,因为可以一个任务单独专门接收数据,这样的话防突发的功能会更明显,不依赖专门的处理数据任务结束才能收下一包数据。
发送数据,如果没有缓冲区,那么对于依赖交互重传的数据将无法单周期多包发送。比如一个以太网数据必须收到对方确认帧才会发下一包数据,那么发送段必须要等待收到对方确认帧才能发下一包数据,期间有什么发送数据都无法发送。

总结:队列(准确来说是读、写两个指针)可以实现单消费者单生产者共享资源问题,另外队列具有防突发和隔离硬件的功能,在单生产者单消费者模型、单生产者多消费者模型中是优先推荐使用的处理策略

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
##KodExplorer (http://kalcaddle.com/) ###ver2.61(2014.7.12) `商业版授权请联系:kalcaddle#qq.com` #### 1.是什么: - Kodexplorer为千帆网络工作室开发的一款服务器文件管理程序。 - 完美取代FTP管理:可用于服务器文件管理,zip解压缩 备份还原、支持图片、音乐、视频预览、office、pdf等格式在线预览。文件夹拖拽上传……。 - 在线编程:支持几乎所有编程语言的在线编辑(高亮,多光标编辑.堪比本地的sublime) - 极佳的操作体验:及其便捷的快捷键支持,让你拥有本地化的体验 - 中文等多语言支持:中文编码全面兼容,文件编辑自动适配。 - 超快的速度:全面采用Ajax+Json进行数据通信,毫秒级的响应速度; - 全平台兼容性:Win Linux Mac (Apache、Nginx、IIS) #### 2.使用场景: - 取代FTP,服务端、客户端软件等复杂的安装配置。kod可以一键安装随处使用. - 你可以用它来管理你的服务器(备份,在线解压缩,版本发布....) - 你可以把他当做管理linux的一个操作系统界面 - 可以用来作为私有云存储系统,存储你的文件... - 当然你也可以用来分享文件 - Web IDE / browser code editor awesomeness - 更多场景等你来挖掘!…… #### 3.使用说明 管理员: admin/admin 普通用户:demo/demo 游客用户:guest/guest [如何使用] 下载程序,解压上传到你的服务器路径下,data目录设置777权限。访问体验超便捷的服务吧! (data目录没有写权限会导致配置修改不能保存、不能新建用户等) [关于上传问题] 程序没有做任何限制,如果需要上传大文件,则修改 php.ini:`upload_max_filesize = 1000M post_max_size = 1000M` [关于解压缩问题] 程序不做任何限制,如若失败请设置php内存限制。memory_limit 1000M [关于兼容性] 建议使用chrome firefox ie9+ 体验更完整。ie8以下基本上不做兼容处理。chrome支持文件夹拖拽上传。 [文件打开] office文件在线预览功能,服务器必须在公网(外部能访问该服务器) [忘记密码] 修改data/system/member.php 密码为明文的md5值 例如将admin密码重设为admin 则修改第一行:"name":"admin","password":"21232f297a57a5a743894a0e4a801fc3" ![](https://cloud.githubusercontent.com/assets/3761968/2583304/764f562a-b9cf-11e3-8e59-afdbdffc20eb.png) ###ver2.61 `2014/7/12` ---- ####update: - 实时搜索,根据搜索框内容变化,实时选中匹配到的结果; - 弹出搜索框遍历子文件夹递归搜索 - session key 加入kod_前缀 避免和其他系统key冲突 - 编辑器选中优化 选择鼠标到窗口外事件处理 ####fix bug:(bug解决和程序优化) - backspace后退截获浏览器事件,作为后退前一次访问的文件夹; - 搜索首字母不匹配问题 - 弹出层中的弹出层关闭,父窗口失去焦点问题。 - 代码中grunt部分代码拆分开,放到程序外面;提交到git、osc - 桌面:删除alert enter快捷键删除 - install 检测 加入跳过,(只判断用到的函数) 加入多语言 - zip压缩没有权限 提示红色,false 统一查找 - 登录成功后 验证码输错清除 - 非root用户拖拽到文件夹问题 - 非root解压问题 不能解压 - list oexe 图标问题 - 用户目录不存在判断 - fileCahe 互斥锁 reset 不用 - ie 8~10样式问题调整 ###ver2.6 `2014/7/6` ---- ####update: - 完全性优化;加入严格的校验机制 - 首次运行环境检测[data目录检测,必须的函数支持提示] - 上传已存在处理——创建副本(另外包括粘贴,解压) - 选中优化 ctrl选中拖拽 - 键盘快捷键选中文件,多个字符

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值