一、互斥的四个概念
我们把大家都能看到的资源叫做:公共资源
a、互斥:任何一个时刻,都只允许一个执行流在进行共享资源的访问——加锁
b、我们把任何一个时刻,都只允许一个执行流进行访问的共享资源叫做临界资源
c、临界资源需要通过代码访问,凡是访问临界资源的代码,叫做临界区。系统资源我们没怎么好管理,但是访问系统资源的代码我们却很好管理。
存在临界资源的原因主要是由于系统资源有限,多个进程或线程需要共享这些资源。如果同时有多个进程或线程同时访问一个临界资源,那么就会出现互斥访问问题,即可能会发生资源冲突,导致系统崩溃或产生错误。
因此,在设计多任务操作系统时,需要实现一些机制来保证对临界资源的访问是互斥的,如使用信号量、互斥量等同步机制,确保同一时间只有一个进程或线程访问临界资源,从而保证系统的稳定性和可靠性。
共享内存:多个进程或线程需要同时访问的内存区域。
文件系统:多个进程或线程需要同时读写的文件。
数据库:多个进程或线程需要共享的数据库。
硬件设备:多个进程或线程需要共享的硬件资源,如打印机、网络接口卡等。
信号量:用于控制多个进程或线程并发访问的系统资源,如缓冲区、管道等。
锁:用于控制对临界区的访问,防止并发访问造成数据不一致、竞态条件等问题。
d、原子性:只有两种状态的属性,比如:要么不做,要么做完!
二、认识信号量
举一个例子:就像我们去一个比较热门的返点吃饭一样,这家饭店里一般都是满客的状态,如果你想一去就有点吃的话,就需要预约一张桌子,然后在那天那顿饭那张桌子只有你才能落座。其他人想吃的话就只能等你离开。
在这个例子中,预约这个操作对于返点的作用是什么:
1、防止餐桌与客人数量的不匹配。
2、避免同一张桌子同时被两个客人争夺。
如果我定的是VIP包厢,只有一一张桌子,这就形成了上文说的互斥这种情况。
我们要说的信号量其实就是,一家店老板手上的一个小本本,上面时刻记录了这家店还剩下多少张桌子没有被预约出去。
也就是说,信号量本质上就是一个计数器:int count=??
客人就是不同的执行流,餐桌就是临界区中的一个个临界资源。
比如count 初始为8,每次来一个执行流count就会-- ——————p操作
如果申请失败了:
if(count>0)count--;
else 挂起阻塞
每次一个执行流结束访问就会让count++————————————v操作
所有的进程都能看到信号量,所以它是共享资源,所以信号量的原子性对于临界区来说非常重要,同一个时刻信号量只能有一个值,不允许阻塞,要么++要么--,不能有任何的中间状态。