南乐县住房和城乡建设局网站,wordpress 主题盗,安徽合肥建设局网站,沧州app开发目录1. POSIX信号量1.1 概念2. 基于环形队列的生产消费者模型2.1 环形队列的基本原理2.2 基本实现思想3. 多生产多消费1. POSIX信号量
1.1 概念 信号量本质是一个计数器#xff0c;申请了信号量以后#xff0c;可以达到预定临界资源的效果。 POSIX信号量和SystemV信号量相同…
目录1. POSIX信号量1.1 概念2. 基于环形队列的生产消费者模型2.1 环形队列的基本原理2.2 基本实现思想3. 多生产多消费1. POSIX信号量
1.1 概念 信号量本质是一个计数器申请了信号量以后可以达到预定临界资源的效果。 POSIX信号量和SystemV信号量相同都可以用于同步操作达到无冲突访问共享资源的目的。但POSIX可以用于线程间同步。
在未加锁情况下如果多个线程同时对临界资源进行访问操作是极度不安全的所以想要实现多个线程并发需要有信号量的申请。
每个线程申请了信号量以后相当于对一块临界资源进行了预定并且将其分成一个个小资源每个线程同时访问该临界资源不同区域达到多线程并发的效果。
对于每个线程来说想访问临界资源。都必须先申请信号量资源这就涉及到了信号量的数目多少。 P、V操作
这个过程其实就是对信号量进行加加减减。申请信号量的过程有成功或者失败成功就是count–失败就是挂起等待即P操作释放信号量就是count即V操作。 PV操作的原子性实现
PV操作的原子性其实是对于其他PV操作而言的即一个P或V操作不能被其他的PV操作给打断即需要实现PV操作的互斥。那么我们可以把PV操作的代码当成临界区保证只有一个进程能访问临界区即可。实现对临界区资源的互斥访问的方法有很多种比如Peterson算法禁用中断加锁等等等 信号量的优缺点
优点简单表达能力强用PV操作可以解决多种类型的同步/互斥问题 缺点不够安全PV操作使用不当容易产生死锁遇到复杂同步互斥问题实现复杂 初始化信号量 参数
pshared:0表示线程间共享非零表示进程间共享 value期望申请的信号量初始值 销毁信号量 等待信号量
功能等待信号量会将信号量的值减1 这其实是申请信号量的函数
是经典的P操作在申请信号量的过程中有重要作用。 发布信号量
功能发布信号量表示资源使用完毕可以归还资源了将信号量值加1 这个便是V操作和V操作形成对比。
2. 基于环形队列的生产消费者模型
2.1 环形队列的基本原理
多线程的情况下实现一个基于环形队列的生产消费模型来进行环形队列的并发访问。
生产者和消费者开始的时候指向的就是同一个位置在队列为满的时候也指向同一个位置。队列为空的时候应该让生产者先访问队列为满的时候应该让消费者先访问。
所以当队列既不为空又不为满的时候生产者和消费者一定指向的不是同一个位置。
那么我们就可以利用这个原理在生产者和消费者不处于同一位置那么久说明多个执行流访问的是临界资源的不同区域就可以实现并发。 但是这个工作是程序员本身完成的而不是信号量设置好的。
2.2 基本实现思想
对于生产者来说最关心的资源应该是环形队列中空的位置对于消费者来说最关心的资源应该是环形队列中有数据的位置其实就是资源存在的位置。
在这个模型中要遵守几个规则 生产者不能把消费者套一个圈也就是说最多生产一圈消费者就要行动了。 消费者不能超过生产者 当指向同一个位置的时候要根据空、满的状态来判定谁先执行 除此之外生产和消费可以并发执行
对于生产者来说我们申请格子资源格子资源变少了其实就是对格子资源做P操作那么可以放的数据资源更多了那此时也就相当于对数据资源做V操作消费者同理。
所以可以通过释放对方资源的方式来达到数据交互的效果。
3. 多生产多消费
如果想实现多生产者和多消费者同时工作是必须要加锁的而这个加锁的地方是放在P操作之后。
生产者函数如下消费者函数同理
void PutData(const int data)
{sem_wait(space_sem); // Ppthread_mutex_lock(_mtx_);//加锁q[consume_step] data;consume_step;consume_step % cap;pthread_mutex_unlock(_mtx_);//解锁sem_post(data_sem); //V
}举个例子如果想要实现并发如果将锁放在了P操作之前就会造成PV操作之前都必须要申请到锁的情况这其实和单线程没有区别并且申请到了锁以后PV操作如果不成功还是需要从新来申请锁所以效率也会更慢。
而放在P操作之后可以理解为在申请锁之前多个线程就已经申请到了信号量即PV操作是成功的。那么此时只需要等待竞争锁就行了。
而这里正是多生产多消费的优势每次都只能一个线程生产一个线程消费可以并发地获取和处理任务。