【Linux】线程同步之POSIX信号量

带你轻松理解生产者消费者模型!生产者消费者模型可以说是同步与互斥最典型的应用场景了!文末附有模型简单实现的代码,若有疑问可私信一起讨论。


==同步概念:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避免饥饿问题,叫做同步。==

一:POSIX信号量

POSIX信号量和SystemV信号量作用相同,都是用于同步操作,达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步。
信号量本质是挂起等待机制的计数器,描述临界资源数量的计数器,当信号量能申请成功时,直接返回,若不成功,该线程就会在该信号量下挂起等待。
若是二元信号量,则把临界资源当作整体使用,若信号量是多个,那么可以保证临界资源划分为不同区域,那么每个线程想要访问这个区域,就要申请信号量。

初始化信号量:

#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
pshared:0表示线程间共享,非零表示进程间共享
value:信号量初始值

销毁信号量:

int sem_destroy(sem_t *sem);

等待信号量:

功能:等待信号量,会将信号量的值减1
int sem_wait(sem_t *sem); //P()

发布信号量:

功能:发布信号量,表示资源使用完毕,可以归还资源了。将信号量值加1。
int sem_post(sem_t *sem);//V()

二:基于环形队列的生产消费模型

上一篇博客介绍的生产者-消费者的例子是基于queue的,其空间可以动态分配,现在基于固定大小的环形队列重写这个程序(POSIX信号量)

  • 环形队列采用数组模拟,用模运算来模拟环状特性

在这里插入图片描述

  • 环形结构起始状态和结束状态都是一样的,不好判断为空或者为满,所以可以通过加计数器或者标记位来判断满或者空。另外也可以预留一个空的位置,作为满的状态。

三:基于环形队列的生产者和消费者之间的关系

同步:当为空时,一定是生产者先生产,为满时,消费者先消费,其他时候并发。
互斥:体现在生产者与生产者,消费者与消费者之间,同一时刻只允许一个执行流进入临界区访问临界资源。还有就是指向同一位置时,代表着为满或者为空,同一时刻只允许某一方访问临界资源。

四:基于环形队列的生产者消费者模型代码

简单实现的代码:基于信号量与环形队列的生产者消费者模型

猜你喜欢

转载自blog.csdn.net/qq_43727529/article/details/129915715