POSIX信号量
目录
一、相关概念回顾
1.信号量
2.多线程使用资源的两种情况
3.P操作和V操作
二、CP && 基于环形队列的生产者消费者模型
1.环形队列的介绍
编辑
2.基于环形队列的生产者消费者模型的默认规则(通过信号量实现规则的成立)
3.相关的结论
4.单生产单消费的生产者消费者模型的实现思路
三、相关接口介绍
2.int sem_destroy(sem_t *sem);
3.int sem_wait(sem_t *sem);
4.int sem_post(sem_t *sem);
一、相关概念回顾
1.信号量
<1>作用:表明临界资源数量的多少
<2>本质
说法一:本质是一个计数器,是对特定资源的预定机制
说法二:信号量的本质也是临界资源
2.多线程使用资源的两种情况
<1>将目标资源整体使用【mutex 或 2元信号量】
<2>将目标资源按照不同的“块”,分批使用
3.P操作和V操作
<1>P操作本质是--,是原子的
<2>V操作本质是++,是原子的
二、CP && 基于环形队列的生产者消费者模型
1.环形队列的介绍
<1>环形队列为空时:head==tail
环形队列为满时:head==tail
<2>解决该冲突的方法
方法一:利用计数器count
方法二:空一个位置,让head==tail时为空,tail+1==head时为满
2.基于环形队列的生产者消费者模型的默认规则(通过信号量实现规则的成立)
<1>当为空时,只能让生产者先运行
<2>当为满时,只能让消费者先运行
<3>生产者不能把消费者套一个圈以上
<4>消费者不能超过生产者
3.相关的结论
<1>这要生产者和消费者不访问同一位置(即为空或为满时),他们两者就可同时运行
<2>为空:只能【互斥】生产者先【同步】运行
为满:只能【互斥】消费者先【同步】运行
<3>为空或为满时,生产者和消费者需要同步或互斥
4.单生产单消费的生产者消费者模型的实现思路
生产者Equeue() | 消费者Pop() |
资源:空的位置 | 有效数据 |
sem_blank=N | sem_data=0 |
int p_step=0 | int c_step=0 |
P(sem_blank);//sem_blank--(申请信号量) | P(sem_data);//sem_data--(申请信号量) |
在p_step处进行生产(生产) | 在c_step处进行消费(消费) |
p_step++;(更新下标) | c_step++;(更新下标) |
p_step%=N;(维持环形特性) | c_step%=N;(维持环形特性) |
V(sem_data);//sem_data++ | V(sem_blank);//sem_blank++ |
注:若要进行加锁,应该在申请信号量与生产/消费间进行加锁,在维持环形队列特性的操作后进行解锁
三、相关接口介绍
1.int sem_init(sem_t *sem, int pshared, unsigned int value);
<1>头文件:<semaphore.h>
<2>功能:初始化信号量
<3>参数:
sem:指向要要初始化信号量的指针
pshared:指定信号量是否在进程或线程之间共享
value:信号量的初始值(可用资源的数量)
<4>返回值:成功返回0,失败返回-1
2.int sem_destroy(sem_t *sem);
<1>头文件:<semaphore.h>
<2>功能:clean up an unnamed semaphore initialized with sem_init
<3>参数:sem:指向要要初始化信号量的指针
<4>返回值:成功返回0,失败返回-1
3.int sem_wait(sem_t *sem);
<1>头文件:<semaphore.h>
<2>功能:POSIX 线程库中用于操作信号量的函数,用于对信号量进行 P 操作,如果信号量的值大于零,sem_wait
会将其减一并立即返回;如果信号量的值为零,调用线程会阻塞,直到信号量的值变为正数。
<3>参数:sem:指向要要初始化信号量的指针
<4>返回值:成功返回0,失败返回-1
4.int sem_post(sem_t *sem);
<1>头文件:<semaphore.h>
<2>功能: POSIX 线程库中用于操作信号量的函数,用于对信号量进行 V 操作。它会增加信号量的值,如果有线程因等待该信号量而被阻塞,其中一个线程会被唤醒。
<3>参数:sem:指向要要初始化信号量的指针
<4>返回值:成功返回0,失败返回-1