一、同步概念
在保证临界资源安全的前提下,访问临界资源要有一定的顺序性(防止一个线程一直访问,效率低且不合理)
二、条件变量
1、介绍
原生线程库通过条件变量来实现线程同步。
所以条件变量里面一定会有线程队列,通知机制。
条件变量:当一个线程互斥的访问某个变量时,它可能发现在其他线程改变状态之前,什么也做不了。
2、函数
(1)创建条件变量
int pthread_cond_init(pthread_cond_t* restrict cond, const pthread_condattr_t* restrict attr)
创建局部条件变量
cond:输出型参数,返回条件变量。
attr:条件变量属性
pthread_cond_t cond = PTHREAD_COND_INITIALIZER
创建全局条件变量
(2)销毁条件变量
int pthread_cond_destroy(pthread_cond_t* cond)
(3)线程等待
int pthread_cond_wait(pthread_cond_t* restrict cond, pthread_mutex* restrict mutex)
让线程看见条件变量cond后停下等待。
为什么参数有锁?
一般使用此函数是在临界区,此时未解锁,按照需求线程已经等待,下一步是等其他线程处理完数据条件符合才能不让线程等待继续运行,如果此时不解锁其他线程就无法执行,此时就是死锁问题,传锁是在函数内部进行解锁,函数返回在让原线程竞争锁,最后运行。
(4)等待成功唤醒线程
int pthread_cond_broadcast(pthread_cond_t* restrict cond)
唤醒全部线程
int pthread_cond_signal(pthread_cond_t* restrict cond)
唤醒一个线程
三、生产消费模型
是多执行流并发模型
321原则
1:一个交易场所(特定数据结构形式存在的一段内存空间)
2:两个角色(生产角色,消费角色):生产线程,消费线程
3:三种关系:生产和消费(互斥),消费和消费(互斥),生产和消费(互斥&&同步)
实现生产消费模型本质通过代码实现321原则,用锁和条件变量实现3中关系。
如果生产快消费慢(对应下载任务快,处理任务慢)就单生产多消费
如果生产慢消费快(对应下载任务慢,处理任务快)就多生产单消费
运行结果:
四、POSIX信号量
1、介绍
在信号量那一章重点讲过,详见http://t.csdnimg.cn/JZNls
本质就是一个计数器,是资源的预定机制
预定:PV操作,在外部可以不判断资源是否满足使用条件就能知道内部资源情况
2、函数
创建信号量 int sem_init(sem_t* sem, int phared, unsigned int value)
sem:输出型参数,返回申请的信号量id
pshared:是否多线程共享
value:设置信号量的初始个数
销毁信号量 int sem_destroy(sem_t sem)
信号量P操作(申请信号量,信号量--)int sem_wait(sem_t sem)
信号量V操作(归还信号量,信号量++)int sem_post(sem_t sem)
五、环形队列生产消费模型
1、基于POSIX信号量设计
实现逻辑:
一开始
数据信号量:0 空间信号量:N
_sem_data = 0 _sem_space = N
中间过程
生产者:申请空间 P(_sem_space--) 增加数据 V(_sem_data++)
消费者:申请数据 P(_sem_data--) 增加空间 V(_sem_space++)
多生产多消费要加锁,因为各自的下标就是临界资源。
一共两把锁,消费者们竞争一把,生产者们竞争一把。