操作系统 信号量与PV操作

信号和信号量的区别

信号:一种简洁的通信方式,进程或内存均可使用信号通知一个进程由某种事情发生.除用于进程之间的通信外,进程也可以发送信号给进程自身(如函数kill(),raise()等).

在操作系统中,进程之间经常会存在互斥(都需要共享独占性资源时) 和同步(完成异步的两个进程的协作)两种关系.为了有效的处理这两种情况,狄克斯特拉(W.Dijkstra)在1965年提出信号量 (semaphore)和PV操作.

    信号量:

    信号量是一种特殊的变量,实际上就是用来控制进程状态的一个代表某一资源的存储单元表现形式是一个整型S和一个队列.

    PV操作:

    P操作和V操作是执行时不被打断的两个操作系统原语。执行P操作P(S)时信号量S的值减1,若结果不为负则P(S)执行完毕,否则执行P操作的进程暂停以等待释放。执行V操作V(S)时,S的值加1,若结果不大于0则释放一个因执行P(S)而等待的进程.

    P操作:也称为down()/wait()操作,使S=S-1,若S<0,进程暂停执行,放入信号量的等待队列.

    V操作:也称为up()/signal()操作,使S=S+1,若S<=0,唤醒等待队列中的一个进程.

(1)完成互斥控制:

    为了保护共享资源,不让多个进程同时访问这个共享资源,换句话说,就是阻止多个进程同时进入访问这些资源的代码段,这个代码段称为临界区(也称为管程),这种一次只允许一个进程访问的资源称为临界资源.为了实现进程互斥地进入自己的临界区,代码可以如下所示:

P(信号量S)

    ......

    临界区(访问临界资源的代码段)

    ......

V(信号量S)

    由于只允许一个进程进入,因此信号量中整型值的初始应设为1.该值表示可以允许多少个进程进入,当该值<0时,其绝对值就是等待使用临界资源的进程数,也就是等待队列中的进程数.而当一个进程从临界区出来时,就会将整型值加1,如果等待队列中还有进程,则调入新的进程进入(唤醒).

(2)完成同步操作http://write.blog.csdn.net/postedit?ref=toolbar

    最简单的同步形式是:进程A在另一个进程B到达L2以前,不该不该前进到超过L1,这样就可以使用以下程序表示:

进程A                                                    进程Bhttp://write.blog.csdn.net/postedit?ref=toolbar

......                                                         ......

L1:P(信号量S)                                      L2:V(信号量S)

......                                                        ......http://write.blog.csdn.net/postedit?ref=toolbar

    因此,要确保进程B执行V操作之前,不让进程A的运行超过L1,因此信号量的初值就应该为0.这样,如果进程A先执行到L1,那么执行P操作后,信号量的整型值就会小于1,也就停止执行.直到进程B执行到L2时,将信号量的整型值加1,并唤醒它以继续执行.


备注:中国读者常常不明白这一同步机制为什么叫PV操作,原来这是狄克斯特拉荷兰文定义的,因为在荷兰文中,通过叫passeren,释放叫vrijgeven,PV操作因此得名。这是在计算机术语中不是用英语表达的极少数的例子之一。http://write.blog.csdn.net/postedit?ref=toolbar

生产者------消费者问题

该问题的基本工作模式为:如果缓冲区为空则消费者不能取;如果缓冲区为满则生产者不可以继续生产。
                                         如果缓冲区满,需要唤醒消费者;如果缓冲区为空则需要唤醒生产者 

N个缓冲区;
     如果只有一个信号量empty时,则:empty = N,in表示生产者放入缓冲区的商品的个数、out表示消费者取出
商品个数.in、out为共享变量。因此为了防止多个进程同时修改它们,将对他们的操作放在PV操作中。

Producer:
                     p(empty)//如果empty==0,则生产者进程自我阻塞。
                      p(mutex)
                       in:=in+1;
                      v(mutex)

   Consumer:
                       v(empty)
                       
p(mutex)
                       out:=out+1;
                       v(mutex)

小结:以上程序缺少了唤醒操作。因此引入多个信号量。用于唤醒阻塞的进程

Producer:
                     p(empty) //如果empty==0,则生产者进程自我阻塞。
                      p(mutex)
                       in:=in+1 mod N;
                      v(mutex)
                      v(full)
       Consumer:
                       p(full)
                       
p(mutex)
                       out:=out+1 mod N;
                       v(mutex)

 

                                            v(empty)
对于in、out取余的原因是为了用于循环。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值