同步互斥

来源:互联网 发布:中级程序员报考条件 编辑:程序博客网 时间:2024/05/17 23:29

同步:为了完成某个任务而建立的两个或多个进程,这些进程为了需要在某些位置上协调它们的工作次序而等待、传递信息所产生的制约关系。进程间的制约关系就是源于它们之间的相互合作。

整型信号量:整型信号量被定义为一个用于表示资源数目的整型量S,wait和signal操作可描述为

wait(S)

{

while (S<=0);

S = S-1;

}

signal(S)

{

S=S+1;

}

记录型信号量:记录型信号量不需要忙等。除了需要一个代表资源数目的整型变量value之外,还需要一个进程链表L,用于链接所有等待该资源的进程。记录型信号量由于采用记录型数据结构而得名。

typedef struct

{

int value;

struct process *L;

}semaphore;

相应的wait 和signal操作如下:

void wait(semaphore S)

{

S.value--;

if(S.value < 0)

{

add this process to S.L;

block(S.L);//自我阻塞,放弃处理机 遵循让权等待

}

}”

void signal (semaphore S)

{

S.value++;

if(S.value <= 0)

{

remove a process P from S.L;

wakeup(P);

}

}


   现在我们假设我的电脑有两台打印机,所以S.value的初值为2,表示系统打印机的数目,称为资源信号量。进程B请求打印,那么系统对它执行一次wait操作,执行S.value:=S.value-1语句后S.value减1,S.value的值变为1,表示有一个资源空闲。执行if语句,S.value不小于0,结束。然后又来了一个进程B请求打印,系统对它又执行一次wait操作,执行S.value:=S.value-1语句后S.value减1,S.value的值变为0,表示没有空闲的资源。执行if语句,S.value不小于0,结束。又来一个进程C请求打印,系统对它又执行一次wait操作,执行S.value:=S.value-1语句后S.value减1,S.value的值变为-1,表示有一个进程没有得到打印机资源。执行if语句,S.value小于0,执行block(S,L),进行自我阻塞,放弃处理机,并插入到信号量链表S.L中。此时S.value的绝对值表示了在该信号量链表中已阻塞进程的数目。所以这个时候阻塞的进程为一个,即是进程C。
      系统运行了一段时间后,A进程结束,在结束前执行了signal操作,当执行到S.value:=S.value+1语句时,S.value加1,即S.value变为0.然后执行 if 语句,S.value小于等于0,执行wakeup(S,L),从S.L链表中唤醒C进程。过了一会,B进程结束,同样执行signal操作,S.value变为1,表示有一个资源空闲,执行if语句,S.value不小于等于0,直接结束。接着C进程执行wait操作,S.value变为0。然后A进程结束,S.value变为1。紧接着C进程也结束了,S.value变为2。S.value最终等于初值,等待其他的进程进行资源请求。


利用信号量实现同步:
semaphore s=0;
p1()
{
  ...
  x;//语句x
  v(s);//通知进程p2,语句x已经执行完毕
  ...
}
p2()
{
  ...
  p(s);//当x未执行则陷入等待
  y;//此时x语句已执行完,可以执行y语句了
  ...
}
互斥:当一个进程进入临界区使用临界资源是,另一个进程必须等待,当占用临界区资源的进程退出临界区以后才允许进入临界区,访问资源。注意,这里的一个并非卡死就一次只能一个进程访问临界资源。当信号量个数大于1的时候,一次可以有多个进程同时访问临界资源。前文的互斥定义只是最原始的定义。
利用信号量实现互斥:


semaphore s=1;
p1()
{
   ...
   p(s);
   ...//临界区
   v(s);
   ...
}
p2()
{
   ...
   p(s);
   ...//临界区
   v(s);
   ...
}




生产者和消费者详解待整理。
0 0
原创粉丝点击