操作系统之进程同步

为什么要有进程同步

直接谈进程同步的概念有点抽象,我们先聊一聊为什么要有进程同步机制。我们的计算机系统刚开始是单道批处理系统,意思就是同一时间段内只能运行一个程序,这个程序运行完,才能运行另一个程序,这样就会导致运行效率太低,系统中的资源得不到充分的利用。怎么解决呢,就发明了多道批处理系统,多道程序并发执行,这样大大提高了系统资源的利用率。但是这种系统就会产生一些问题,比如有的资源,比如显示器,cpu,同一时间肯定只能一个程序使用,多个程序肯定不能同时使用显示器,这就是互斥关系,另外,有的两个进程间存在这样的制约关系:A程序的输出是B程序的输入,这是同步关系,为了解决这些问题,我们引入了进程同步机制。

进程同步的方法

怎么用进程同步的方法解决上述问题呢,其中一个方法就是信号量机制。

信号量机制

信号量机制是由荷兰的dijkstra发明的,有三种信号量机制,分别是
整型信号量结构体型信号量AND型信号量

整型信号量
说白了就是用一个整数来进行管理,这个整数代表资源的数目,众所周知,对资源的操作有两种,一种是使用,一种是释放。他们分别对应两个函数:wait和signal

wait(S){
  while(S<=0);
  S--;
}
signal(S){
  S++}

wait方法的意思就是首先看资源可不可以用,如果不可以用,也就是S<=0,它会一直等下去,直到S成为一个正数,然后S自减;signal的意思是使用完资源后释放资源,S自增。

结构体型信号量

为什么整型信号量用的好好的,要造一个结构体型信号量呢?因为整型信号量有个问题:我们会发现当S<=0的时候,会一直执行循环,也就是进程会处于忙等的状态。我们要解决忙等,也就是要让进程符合“让权等待”,就是要在进程无法使用资源的时候,释放处理机。那么问题就来了,该让哪个进程访问临界资源呢?我们可以使用一个链表来解决这个问题。所以我们就用一个结构体来描述资源,这个结构体长这样:

typedef struct{
  int value;
  struct process_control_block *list;
}semaphore;

这个结构体里边有两个变量,一个是value,用来记录资源的个数,下边这个是指针,指向下一个要使用临界资源的进程。
所以之前的使用和释放资源的函数就变成了这样:

wait(semaphore *S){
  S->value--;
  if(S->value<0)  block(S->list);
}
signal(semaphore *S){
  s->value++;
  if(S->value<=0)  wakeup(S->list);
}

使用信号量机制解决问题

上边咱们只是简单介绍了一下信号量机制,但别忘了咋们是要解决互斥关系和同步关系这两个问题的。

实现互斥关系
假设两个进程PA,PB具有互斥关系,也就是他们俩要使用一个临界资源,怎么做呢,我们设置一个mutex信号量,初值设为1,这样的话刚开始两个进程都能使用,他们使用的时候,先wait,wait完自然要让mutex-1,这样mutex为0,另一个就不能用了,使用完以后signal(释放),mutex重新变成1,另一个进程依然可以使用该临界资源。

semaphore mutex=1;
PA(){
  while(1){
    wait(mutex);
    临界区
    signal(mutex);
    剩余区
  }
}
PB(){
  while(1){
    wait(mutex);
    临界区
    signal(mutex);
    剩余区
  }
}

实现前驱关系
假设P1和P2有前驱关系,P1执行完,P2才能执行,那么怎么实现呢?可以设置一个公共的信号量S,初值设为0

进程P1中:S1;signal(S);
进程P2中:wait(S);S2;

这个是什么意思呢,就是先执行P1的语句,然后释放S,也就是S++,这样当P2执行wait的时候才可以执行,否则,不执行signal的话,S就为0,P2也无法执行,这样就实现了P1和P2的前驱关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值