进程同步

1.什么是进程同步?
进程同步是一种能让多个进程有秩序的运行的机制,它具体分为:硬件同步机制,信号量机制,管程机制。

2.相关专业术语
(1)间接相互制约关系:几个进程通过共享的资源形成的制约关系。
(2)直接相互制约关系:几个进程为完成同一个任务形成的关系。
(3)临界资源:一次只能供一个进程使用的资源(如打印机),故各进程之间采用互斥的方式实现对这种资源的共享。
(4)临界区:有临界资源知,不论是硬件临界资源还是软件临界资源,各进程必须要互斥的对它进行访问。而人们则把每个进程中访问及临界资源的那段代码称为临界区,所以临界区就是一段代码组成的。
(5)同步机制应遵循的规则:空闲让进,忙则等待,有限等待(对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免进入“死等”),让权等待(当进程不能进入自己的临界区时,应立即释放处理机,以免陷入“忙等”)

3.锁的概念
在对临界区进行管理时,可以将标志一个锁,“锁开”进入,“锁关”等待,初始时锁是打开的。每个要进入临界区的进程必须先对锁进行测试,当锁未开时,则必须等待,直至锁被打开。反之,当锁是打开的时候,则立即把其锁上,以阻止其他进程进入临界区,显然,为防止多个进程同时测试到锁为打开的情况,测试和关锁操作必须是连续的,不允许被分开。

4.硬件同步机制
(1)利用关中断实现互斥:在进入锁测试之前关闭中断,直到完成锁测试并上锁后才能打开中断。

(2)利用Test-and-Set指令实现互斥:

boolean TS(boolean *lock)
{
     boolean old;
     old = *lock;
     *lock = TRUE;
     return old;
}
利用TS指令实现互斥的循环进程结构如下
do{
    whileTS(&lock);
    critical secition;
    lock = FALSE;
    remainder section;
}while(TRUE)

(3)利用Swap指令(对换指令)实现进程互斥:

void Swap(boolean *a,boolean *b)
{
   boolean temp;
   temp = *a;
   *a = *b;
   *b = temp
}

每一个临界资源设置一个全局的布尔变量lock,初值为false,在每个进程中再利用一个局部变量key,利用Swap实现互斥。
循环描述如下:

do{
   key = TRUE;
   do{
     Swap(&lock,&key);
     }while(key!=FALSE);
     临界区操作;
     lock = FALSE;
     .....
  }while(TRUE)

(4)信号量机制(已被广泛应用)

1)整型信号量:
整形信号量是一个用于表示资源数量的整型量,用S表示,除了初始化外,它只能通过两个标准的原子操作wait(S)和signal(S)【又称P,V操作】来访问,它们的描述如下:

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

signal(S){
   S++;
 }

当一个进程在修改某信号量时,其他进程不能对该信号量进行修改。

2)记录型信号量
通过整型信号量中的wait(S)中,我们知道只要是信号量S<=0,就会不断测试,因此,该机制没有遵循“让权等待”原则,而让进程陷入“忙等”。所以我们需要改进,因此记录型信号量出现。
记录型信号量是由于采用了记录型的数据结构而得名:

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

value代表资源数目,list是一个进程链表指针,用于链接所有等待进程

相应的,wait(S)和signal(S)操作如下:

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

上述的进程互斥针对的是多并发进程共享一个临界资源的情况。

3)AND型信号量
在有些情况,一个进程往往需要获得两个或更多的资源后才能执行任务,因此AND型信号量出现。AND同步机制的基本思想是:将进程在运行过程中需要的所有资源,一次性全部分配给进程,待进程使用完后再一起释放,只要有一个资源未能分配给进程,其他所有资源可能为之分配的资源也不会分配给它。由死锁理论可知,这样就可避免上述死锁情况发生。为此在wait操作中增加一个“AND”条件,故称为AND同步,或称为同时wait操作,即Swait(Simultaneous wait)定义如下:

Swait(S1,S2,...,Sn)
{
   while(TRUE)
   {
    if(Si>=1&&...&&Sn>=1){
      for(i = 1;i<=n;i++)Si--;
      break;
      }
    else {
      place the process in the waiting queue associated with the first Si 
      found with Si>1,and set the program count of this process to the 
      beginning of Swait operation
      }
   }
}
Ssignal(S1,S2,...Sn){
 while(TRUE){
      for(i = 1;i<=n;i++){
           Si++;
           Remove all the process waiting in the queue associated with Si                     
           into the  ready queue
           }
       }
  }

4)信号量集
在前面所述的记录型信号量机制中,wait(S)或signal(S)操作仅能对信号量进行加1或减1操作,意味着每次只能对某类临界资源进行一个单位的申请或释放,当一次需要N个单位时,便要进行N次wait(S)操作,这显然是低效的,甚至会增加死锁的概率。此外,在有些情况下,为了确保系统的安全,当申请的资源数目低于某一下限时,还必须进行管制,不分配资源。因此,当进程申请某类资源时,在每次分配之前,都必须测试资源的数目,判断是否大于可分配的下限值,决定是否给予分配。基于上述两点,我们可以对AND信号量机制加以扩充,对进程所申请的所有资源以及每类资源不同的资源需求量,在一次P,V原语操作中完成申请或释放。进程对信号量的的测试值是该资源的分配下限值t,即要求S>=t,否则不给分配,一旦允许分配,进程对该资源的需求值为d,表示资源占用量,进行S = S-d的操作,由此形成一般化的信号量集机制,对应的Swait和Ssignal格式为:

Swait(S1,t1,d1,…Sn,tn,dn);

Ssignal(S1,d1,…,Sn,dn);

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值