操作系统——进程同步(三)

进程同步中很著名的问题就是生产者-消费者问题,描述如下:
有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有 n 个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可从一个缓冲区中取走产品去消费。尽管所有的生产者进程和消费者进程都是以异步方式运行的,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。
生产者-消费者问题代码有很多种形式,但是面对的问题都是一个:消费者进程和生产者进程在并发执行的时候,有一个共享变量(假设为counter)若生产者对它做加 1 操作,消费者对它做减 1 操作,这两个操作在用机器语言实现时, 常可用下面的形式描述:
register1:=counter; register2:=counter;
register1:=register1+1; register2:=register2 - 1;
counter:=register1; counter:=register2;
假设 counter 的当前值是 5。如果生产者进程先执行左列的三条机器语言语句,然后消费者进程再执行右列的三条语句,则最后共享变量counter 的值仍为 5; 反之,如果让消费者进程先执行右列的三条语句,然后再让生产者进程执行左列的三条语句,则 counter 值也还是 5,但是,如果按下述顺序执行:
register1:=counter; (register1=5)
register1:=register1+1; (register1=6)
register2:=counter; (register2=5)
register2:=register2 - 1; (register2=4)
counter:=register1; (counter=6)
counter:=register2; (counter=4)
正确的 counter 值应当是 5,但现在是 4。
解决此问题的关键是应把变量 counter 作为临界资源处理,亦即,令生产者进程和消费者进程互斥地访问变量 counter。
同步机制的关键就是关于临界区的互斥处理,这个互斥处理里面的关键就是在临界区外的进程不能够阻止其他进程进入临界区。具体的解决方式:
信号量机制:
整型信号量:整型信号量定义为一个用于表示资源数目的整型量 S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作(Atomic Operation) wait(S)和 signal(S)来访问。很长时间以来,这两个操作一直被分别称为 P、V 操作。Wait(S)和 signal(S)操作可描述为:
wait(S):
while S<=0 do no-op;
S:=S - 1;
signal(S): S:=S+1;
wait(S)是一个原子操作,不能停下来,对S值的测试和做S:=S-1操作是都不能中断。
记录型型号量:在整型信号量机制中的 wait 操作,只要是信号量 S≤0,就会不断地测试。因此,该机制并未遵循“让权等待”的准则,而是使进程处于“忙等”的状态。记录型信号量机制则
是一种不存在“忙等”现象的进程同步机制。但在采取了“让权等待”的策略后,又会出现多个进程等待访问同一临界资源的情况。为此,在信号量机制中,除了需要一个用于代表资源数目的整型变量 value 外,还应增加一个进程链表指针 L,用于链接上述的所有等待进程。记录型信号量是由于它采用了记录型的数据结构而得名的。它所包含的上述两个数据项可描述为:

type semaphore=record
    value: integer;
    L: list of processend

相应地,wait(S)和 signal(S)操作可描述为:

procedure wait(S)
    var Ssemaphorebegin
        S.value:=S.value-1if S.value<0 then block(S.L);
    end
procedure signal(S)
    var S: semaphore;
    begin
        S.value:=S.value+1if S.value<=0 then wakeup(S.L);
    end

S.value 的初值表示系统中某类资源的数目,因而又称为资源信号量。对它的每次 wait 操作,意味着进程请求一个单位的该类资源,使系统中可供分配的该类资源数减少一个,因此描述为S.value:=S.value-1;当 S.value<0 时,表示该类资源已分配完毕,因此进程应调用 block 原语,进行自我阻塞,放弃处理机,并插入到信号量链表S.L 中。可见,该机制遵循了“让权等待”准则。此时 S.value 的绝对值表示在该信号量链表中已阻塞进程的数目。对信号量的每次 signal 操作,表示执行进程释放一个单位资源,使系统中可供分配的该类资源数增加一个,故 S.value:=S.value+1 操作表示资源数目加 1。若
加 1 后仍是 S.value≤0,则表示在该信号量链表中,仍有等待该资源的进程被阻塞,故还应调用 wakeup 原语,将 S.L 链表中的第一个等待进程唤醒。
AND型信号量:在有些应用场合,是一个进程需要先获得两个或更多的共享资源后方能执行其任务。假定现有两个进程 A和 B,他们都要求访问共享数据 D 和 E。这种情况下很容易发生死锁,解决方式就是“要么不给,要么全给”A要么就是同时得到D和E,要么就是D,E都得不到。
信号量集:这是对AND型信号量进行的扩充,

Swait 操作可描述如下,其中 S 为信号量,d 为需求值,而 t 为下限值。
    Swait(S 1 ,t 1 ,d 1 ,…,S n ,t n ,d n )
        if S i >=t 1 andand S n >=t n then
            for i:=1 to n do
                S i :=S i - d i ;
            endfor
        else
        Place the executing process in the waiting queue of the first S i with S i <t i and set its program counter
to the beginning of the Swait Operation.
        endif
    Ssignal(S 1 ,d 1 ,…,S n ,d n )
        for i:=1 to n do
            S i :=S i +d i ;
        Remove all the process waiting in the queue associated with S i into the ready queue
        endfor;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值