Linux下用环形buf以及POSIX版本信号量解决生产者消费者问题
2016-04-24 16:18
423 查看
一、Semaphore(信号量)
Mutex变量是非0即1的,可看作一种资源的可用数量,初始化时Mutex是1,表示有一个可用资源, 加锁时获得该资源,将Mutex减到0,表示不再有可用资源,解锁时释放该资源,将Mutex重新加到1,表示又有了一个可用资源。
信号量(Semaphore)和Mutex类似,表示可用资源的数量,和Mutex不同的是这个数量可以大于1。
即,如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同!
本次使用的是POSIX semaphore库函数,这种信号量不仅可以于同一进程的线程间同步,也可以用于不同进程间的同步。
使用如下:
semaphore变量的类型为sem_t,sem_init()初始化一个semaphore变量,value参数表示可用资源的数量,pshared参数为0表示信号量适用于同一进程的线程间同步。在使用完完semaphore变量之后应该调用sem_destroy()释放与semaphore相关的资源。
调用sem_wait()可以获得资源(P操作),使semaphore的值减1,如果调用sem_wait()时semaphore的值已 经是0,则挂起等待。如果不希望挂起等待,可以调用sem_trywait() 。调sem_post() 可以释放资源(V操作),使semaphore 的值加1,同时唤醒挂起等待的线程。
二、实现生产者--消费者问题
(1).本例中主要使用环形buf与信号量来实现单消费者,单生产者,其环形buf的实现主要用数组下标模环形buf的大小20。
对于生产者而言:不能在生产速度上把消费者套圈。
对于消费者而言:其消费速度不能超过生产者。
本例中主要实现:当生产者所需空格数为0,便挂起等待消费者消费 。当消费者消费数据为0,便挂起等待生产者生产。其生产者空格初始值为20,其消费者数据初始值为0。代码如下:
运行结果:
(2).多生产者,多消费者,修改代码如下,需要分别对生产者,消费者加锁。
运行结果如下:
总结:对于多生产者多消费者,要在其信号量操作内加锁,而不在外部,因为信号量的操作是原子的。并且效率更高。
信号量不是加锁,主要是用来同步的。但是也可以用信号量操作实现加锁。
本文出自 “柏拉图的永恒” 博客,请务必保留此出处http://ab3813.blog.51cto.com/10538332/1767252
Mutex变量是非0即1的,可看作一种资源的可用数量,初始化时Mutex是1,表示有一个可用资源, 加锁时获得该资源,将Mutex减到0,表示不再有可用资源,解锁时释放该资源,将Mutex重新加到1,表示又有了一个可用资源。
信号量(Semaphore)和Mutex类似,表示可用资源的数量,和Mutex不同的是这个数量可以大于1。
即,如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同!
本次使用的是POSIX semaphore库函数,这种信号量不仅可以于同一进程的线程间同步,也可以用于不同进程间的同步。
使用如下:
semaphore变量的类型为sem_t,sem_init()初始化一个semaphore变量,value参数表示可用资源的数量,pshared参数为0表示信号量适用于同一进程的线程间同步。在使用完完semaphore变量之后应该调用sem_destroy()释放与semaphore相关的资源。
调用sem_wait()可以获得资源(P操作),使semaphore的值减1,如果调用sem_wait()时semaphore的值已 经是0,则挂起等待。如果不希望挂起等待,可以调用sem_trywait() 。调sem_post() 可以释放资源(V操作),使semaphore 的值加1,同时唤醒挂起等待的线程。
二、实现生产者--消费者问题
(1).本例中主要使用环形buf与信号量来实现单消费者,单生产者,其环形buf的实现主要用数组下标模环形buf的大小20。
对于生产者而言:不能在生产速度上把消费者套圈。
对于消费者而言:其消费速度不能超过生产者。
本例中主要实现:当生产者所需空格数为0,便挂起等待消费者消费 。当消费者消费数据为0,便挂起等待生产者生产。其生产者空格初始值为20,其消费者数据初始值为0。代码如下:
运行结果:
(2).多生产者,多消费者,修改代码如下,需要分别对生产者,消费者加锁。
运行结果如下:
总结:对于多生产者多消费者,要在其信号量操作内加锁,而不在外部,因为信号量的操作是原子的。并且效率更高。
信号量不是加锁,主要是用来同步的。但是也可以用信号量操作实现加锁。
本文出自 “柏拉图的永恒” 博客,请务必保留此出处http://ab3813.blog.51cto.com/10538332/1767252
相关文章推荐
- x86 linux系统内核引导流程梳理
- Linux 批量修改文件名
- linux下部署kodexplorer
- linux 终端 tmux简单教程
- OK6410的uboot关闭mmu和cache---嵌入式回归第九篇
- goahead-3.6.2移植到linux
- linux内核分析 期中总结
- linux命令--centos 因别名问题引起的麻烦及解决技巧
- linux下安装androidstudio
- 解析 Linux 中的 VFS 文件系统机制(转)
- 每天一个linux命令:find
- CentOS 7最小安装之后应该尽快做好的几件事情
- Linux是一个多用户多任务的操作系统
- CentOS 6 中设置系统级代理
- Linux内核分析总结-路过的小游侠
- Centos7中安装mysql 5.6
- Linux进程与线程的区别
- Linux 命令的举例需求及解答步骤
- centos 添加epel、remi仓库和ELRepo仓库
- Linux 50个常用命令