信号量机制

1.整数型信号量

  • 整数信号量S
  • 两个原子操作:wait/signal(P/V)

原则

  1. 除了初始化外,整数信号量S只能由wait/signal访问
  • 进入区 设为wait(S)(wait函数是在S大于零的情况下让S递减1)
  • 退出区 设为signal(S)(signal函数是让S递增1)

问题:没有实现让权等待

2.记录型信号量

  • 记录型信号量S
  • 两个原子操作:wait/signal(P/V)

原则

  1. 除了初始化之外,S只能由wait/signal访问
  • wait(S)函数首先让S无条件的减1
    随后判断S,倘若S小于零,则说明没有足够资源,随即阻塞(block)进程
  • signal(S)函数首先让S无条件的加1
    随后判断S,倘若S<=0,就唤醒(wakeup)进程,使得进程进入就绪状态
    不过这并不意味着程序能立即得到调度,要看操作系统

可以实现空闲让进与忙则等待

信号量S的物理含义

  • 对信号量的每次wait操作,意味着进程请求一个单位的该类资源,当S小于0时,表示该类资源已经分配完毕,因此进程应进行自我阻塞
  • 对信号量的每次signal操作,表示执行进程释放一个单位资
    源,操作表示资源数目加1,若加1后仍是S.value <=0,则表示在该信号量链表中,仍有等待该资源的进程被阻塞,将链表中的第一个等待进程唤醒

多进程共享临界资源

  1. 多进程共享临界资源:信号量S的物理含义

  2. 多进程共享临界资源:mutex的初值
    倘若mutex的初值为2,则会出现两个进程同时访问临界区

信号量的应用

1.信号量用于互斥

独木桥问题

Parbegin
VAR mutex : semaphore = 1 ;

  Process S2N :
   Begin
    repeat
    wait( mutex) ;
    go across the bridge ;
    signal(mutex) ;
    until false
   end

  Process N2S :
   Begin
    repeat
    wait( mutex) ;
    go across the bridge ;
    signal(mutex) ;
    until false
   End
Parend

2.信号量用于同步

例:Pi与Po两个进程共享缓冲区B,PI负责读取数据并保存在B中,PO负责打印数据,要求每个数据都必须被打印一次,不能重复不能遗漏
解决方法:Pi与Po各设置一个信号量

Parbegin
  VAR S1,S2 : semaphore = 1, 0 ;

  Process PI :
  Begin
   repeat
    read x from I/O ;
    wait(S1) ;
    B := x ;
    signal(S2) ;
   until false
  end
 
 Process PO :
  Begin
    repeat
     wait(S2) ;
     y := B ;
     signal(S1) ;
     print(y) ;
    until false
   End
Parend 

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议