Chinaunix首页 | 论坛 | 博客
  • 博客访问: 82503
  • 博文数量: 40
  • 博客积分: 1820
  • 博客等级: 上尉
  • 技术积分: 395
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-26 16:12
文章分类

全部博文(40)

文章存档

2011年(8)

2010年(32)

我的朋友

分类:

2010-05-11 22:47:12

2.2 进程间通信
    进程间通信(IPC)有三方面的内容:

  • 一个进程如何向另一个进程传递信息。
  • 保证两个或多个进程在涉及临界活动时不会彼此影响。(对线程适用)
  • 当存在依赖关系时确定适当的次序。(对线程适用)

2.2.1 竞争条件
   
在有些操作系统中,协作进程可能共享一些彼此都能读写的公用存储区。两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,就称为竞争条件race condition)。


2.2.2 临界区

    防止多个进程同时访问共享数据的方式:互斥(mutex

    对共享内存进行访问的程序片段称为临界区临界段critical regioncritical section

    保证使用共享数据的并发进程能够正确和高效的操作的好的解决方案须有以下四个条件:

  • 任何两个进程不能同时处于临界区
  • 不应对CPU的速度和数目有任何假设
  • 临界区外的进程不能阻塞其他进程
  • 不得使进程在临界区外无休止地等待

2.2.3 忙等待形式的互斥

关闭中断

    最简单,每个进程进入临界区先关中断,出临界区再开中断。但是把关中断的权利交给用户是不明智的。

锁变量

    设置一个共享锁变量,初值为0,进程进入临界区之前先测试锁变量,若为0,将其置1然后进入,出临界区时设置0;若为1,则等待其值变为0。不足之处在于,当进程在读锁变量为0之后,置其为1之前CPU将其调度则会出现两个进程同时存在于临界区的情况。

严格交替法


    turn作为一个自旋锁(spin lock)。持续检测一个变量知道它具有某一特定值就称为忙等待busy waiting)。

    上述算法存在的问题:假设进程0访问临界区,当完成非临界区的程序后回到循环开始处时,由于之前将turn置为1,所以只能阻塞,等待进程1turn置为0,但是此时进程1并未访问临界区,因此违反了上述条件3:进程不能被临界区外的进程所阻塞。

Peterson解决方案


访问临界区一共有两个条件:trun==processinterested[other]==TRUE,全符合的话则阻塞在这个循环处,分别看:

  • turn==processinterested[other]==TRUE,即标识位为自己,但另一个进程准备访问临界区
  • turn==processinterested[other]==FALSE,标志位为自己,另一个进程不准备访问临界区
  • turn!=processinterested[other]==TRUE,说明另一个进程在自己之后准备进入临界区,但是对于另一个进程而言,符合turn==processinterested[other]==TRUE,阻塞
  • turn!=processinterested[other]==FALSE,说明在自己之后准备进入临界区的进程已经从临界区中退出。

看这部分的代码时,最好两个进程部分结合起来看。

TSL

需要硬件支持,原理是将一个存储器字读到寄存器中,然后再该内存地址上存一个非零值。

TSL RX,LOCK


2.2.4 睡眠和唤醒

优先级反转问题(priority inversion problem

生产者-消费者问题(有界缓冲区问题)

 


2.2.5 信号量(P/V操作)

信号量(semaphore):

  • down:若大于0,值减一;若等于0,睡眠
  • up:值加一,唤醒

信号量的两种用途:

  • 互斥:如上面程序的mutex,保证同一时刻只有一个进程读写缓冲区和相关变量。
  • 同步:如上面程序的fullempty,保证一定的时间顺序发生或不发生。

2.2.6 互斥

互斥是一个可以处于两态的变量:解锁和加锁。

互斥适用两个过程:一个进程进入临界区时,调用mutex_lock

  • 若互斥是解锁的,进入临界区
  • 若互斥是加锁的,调用者被阻塞

2.2.7 管程

管程(monitor)是一种高级原语。管程是由过程、变量及数据结构组成的集合,它们组成一个特殊的模块或软件包。进程可以在任何需要时调用管程中的过程,但它们不能再管程外的过程中直接访问管程内部的数据结构。

任意时刻在管程中只能有一个活跃进程。

进入管程实现的互斥由编译器负责。

waitsignal,与sleepwakeup很类似,有一点区别:sleepwakeup之所以会失败是因为当一个进程想睡眠时另一个进程试图去唤醒它。管程不会出现这种情况。



2.2.8 消息传递(message passing

sendreceive

消息传递有多中变体,先看如何对消息编址:

  • 为每二个进程分配一个唯一的地址,按进程为消息指定地址。
  • 阴郁一种新的数据结构,信箱。

    聚合(rendezvous)原则:一种策略,send必须在receive之后进行,receive执行后,接受者必须等待send执行。



阅读(709) | 评论(0) | 转发(0) |
0

上一篇:第2章 进程-1

下一篇:第2章 进程-3

给主人留下些什么吧!~~