什么是信号量?
我们来认识一下这四个概念
在理解四个概念之前先理解公共资源(大家都能看到的资源)
1.互斥:
在任何一个时刻,我们都只允许一个执行流在进行共享资源的访问——加锁
比如:我进入了一个房间,然后把门反锁,那么这个房间的资源就只属于我能访问了,别人不能进了,如果别人想进的话,策略有很多,比如操作系统如果看到我占据了这个房间很久就会把
我赶出去,或者我把门打开,让其他人进入
2.临界资源:
我们把任一时刻,都只允许一个执行流在进行访问的共享资源叫做临界资源
临界资源有什么用呢?
在多进程或多线程的环境中,由于多个进程或线程可以同时访问同一个临界资源,可能会出现资源竞争的情况,这时就需要采用一定手段来保护临界资源的访问。
停车场可以看作是一个社会中的临界资源。停车位是裕量有限的,同时多个车辆都需要通过停车场来解决停车问题,这就造成了停车场资源的竞争。
在这种情况下,停车场可以采用一些同步机制,例如设置管理人员来指挥车辆有序进出停车场。如果多个车辆在同一时刻试图争夺同一个停车位,那么停车场中的管理人员可以制定一些标准,例如给优先权的车辆先放行,或者按照先到先得的原则进行排队等待。这样就能够保证停车场的资源访问是有序和互斥的,避免了资源竞争导致的问题,如交通堵塞、停车位浪费等。
3.临界区
什么是临界区呢?
是指在多进程或多线程并发执行的程序中,访问共享资源的一段代码或代码段,要求在同一时刻只能有一个进程或线程访问。
也就是说我们把访问临界资源的代码叫做临界区,因为临界资源是要代码进行访问的
临界区有什么作用呢?
当顾客购买完毕,把商品放到收银台上之后,收银员就需要对这些商品进行结账操作。每一个顾客的结账过程就是一个临界区,因为有多个顾客在同时结账,如果没有同步机制(没有同步机制的话会进行资源的竞争),可能会导致顾客之间的交叉影响和结果出错的情况。
在这种情况下,超市一般采取排队的方式对顾客进行管理,以保证顾客按照一定的先来先服务的顺序进行结账。也就是一个人访问一个收银台,也就是说我们的收银台是临界区。我们是通过
收银台去进行结账的(也就是通过临界区取访问临界资源的);
4.原子性
原子性是指一个操作要么全部执行并且执行过程不可中断,要么不执行,不会存在执行了一部分又停止的情况。
简单点说就是要么做,要么不做
因为如果执行被中断的话,可能资源就被修改了,会导致不可靠和不安全,
所以原子性在在多线程或多进程环境下,原子性是确保共享资源数据同步和线程安全的一种重要机制,也是保证程序正确性和可靠性的关键因素之一。
理解了上述四点后:
我们正式来介绍信号量
简单理解信号量
感性理解这段话:
我去预定座位,那么我就是执行流,预定的这个座位就是临界资源,那我们通过什么
去预定座位的呢,通过app去预定座位,这个app就可以看做是临界区,也就是说
我(执行流)通过这个app(临界区)去访问座位资源(临界资源)
那么这个座位有多少个呢?,这个座位数量对应的就是信号量
信号量的本质:描述资源数量的计数器
所以我们一个进程在想访问临界区的临界资源的时候,需要释放信号去获得座位资源,
这些信号我们看做信号量。我们申请一个信号量就一定能释放信号进入临界区访问临界资源
(座位资源).
那多个人怎么去访问资源呢?
首先我们让多个人看到同一份资源,那么就需要看到
同一个计数器(int count --- 信号量(因为本质是个计数器)),那么我们看到同一份资源
又叫什么呢?我们叫通信,所以信号量由被叫做通信,我们都在抢这个信号量,也
就是我们去抢票,抢到票了,我们就有资格去电影院看电影了
获取信号量的函数,就不介绍了,可以去看其他博主的共享内存的详解,操作方式是差不多的