互斥锁和信号量机制

互斥锁

特性:

1.需要忙等,进程时间片用完才下处理机,违反让权等待
2.优点:等待奇迹不用切换进程上下文,多处理机系统中,若上锁的时间短,则等待的代价很低
3.常用于多处理机,一个核忙等,其他核照常工作,并快速释放临界区
4.不太适合用于单处理机系统,忙等过程中不可能解锁

信号量机制

用户可以使用操作系统提供的一对原语来对信号量进行操作,方便实现进程互斥,进程同步

信号量就是一个变了,可以用一个信号量来表示,系统中某种资源的数量,比如说系统中只有一台打印机,就可以设置一个初始值为1的信号量

原语是一种特殊的程序段,只能一气呵成不可被中断,原语是由开关中断指令实现的,软件方案主要问题是“进入区的各种操作无法一气呵成”,因此只要把进入区和推出区的操作都用原语实现,就能一气呵成

一对原语:wait(S)和signal(S),可以把原语理解诶我们自己写的函数,里面的S是传入的参数

wait和signal也被称为P/V操作来自荷兰语(proberen/Verhogen)

整型信号量

用一个整形的变量作为信号了,用来表示系统中的某种资源数量

比如说系统中有一台打印机

int S=1;

void wait(int S){ //进入区
  while(S<=0);	//	如果资源不够就一直循环等待
  S=S-1;	//	如果资源够就占用一个资源
}

void signal(int S){//退出区
  S=S+1	//用完资源后,在推出区释放资源
}
//process0:
...
wait(S);
//使用打印机的指令
signal(S);
...

//process1
...
wait(S);
//使用打印机的指令
signal(S);
...
  

不满足让权等待,它会一直占用处理机进行while循环直到时间片用完

记录型信号量

整形信号量存在忙等的问题,因此人们提出了记录型信号量,即记录型数据结构表示的信号量

typedef struct{
	int value;				//剩余的资源数量
	struct process *L;	//等待队列
}semaphore;
void wait(semaphore S){
  S.value--;
  if (S.value<0){
    block(S.L);
  }
}

void signal(semaphore S){
  s.value++;
  if (S.value<=0){
    wakeup(S.L);
  }
}

具体例子: https://www.bilibili.com/video/BV1YE411D7nH/?p=32&share_source=copy_web&vd_source=7b850f4882e6be926b6eb30758a00e34&t=995

当S.value<0的时候,进程会主动调用block原语进行自我阻塞,就不会出现忙等的情况,尊旭了“让权等待”

对信号量进行V操作,意味着释放一个单元的该资源,会执行S.value++
完成+1后,如果value依然小于0,那么就会调用wakeup原语,唤醒队列中的第一个进程,从阻塞态-》就绪态

posted @ 2025-09-29 10:17  是我,米老鼠  阅读(19)  评论(0)    收藏  举报