经典进程同步问题

3.4.3 经典进程同步问题

    本节我们讨论几个利用信号量来实现进程互斥和同步的经典例子。这里的主要问题是如何选择信号量和如何安排P、V原语的使用顺序。

    依据信号量与进程的关系,我们可把进程中使用的信号量分成私有信号量和公用信号量。私有信号量是指只与制约进程和被制约进程有关的信号量;公用信号量是指与一组并发进程有关的信号量。

1.生产者一消费者问题

生产者一消费者问题(producer-consumerproblem)是指若干进程通过有限的共享缓冲区交换数据时的缓冲区资源使用问题。假设“生产者”进程不断向共享缓冲区写人数据(即生产数据),而“消费者”进程不断从共享缓冲区读出数据(即消费数据);共享缓冲区共有n个;任何时刻只能有一个进程可对共享缓冲区进行操作。所有生产者和消费者之间要协调,以完成对共享缓冲区的操作。

我们可把共享缓冲区中的n个缓冲块视为共享资源,生产者写人数据的缓冲块成为消费者可用资源,而消费者读出数据后的缓冲块成为生产者的可用资源。为此,可设置三个信号量:full、empty和mutex。其中:full表示有数据的缓冲块数目,初值是0;empty表示空的缓冲块数初值是n;mutex用于访问缓冲区时的互斥,初值是1。实际上,full和empty间存在如下关系:full + empty = N

注意:这里每个进程中各个P操作的次序是重要的。各进程必须先检查自己对应的资源数在确信有可用资源后再申请对整个缓冲区的互斥操作;否则,先申请对整个缓冲区的互斥操后申请自己对应的缓冲块资源,就可能死锁。出现死锁的条件是,申请到对整个缓冲区的互斥操作后,才发现自己对应的缓冲块资源,这时已不可能放弃对整个缓冲区的占用。
如果采用AND信号量集,相应的进入区和退出区都很简单。如生产者的进入区为
Swait(empty,mutex),退出区为Ssignal(full,mutex)。

2.读者一写者问题

读者一写者问题(readers-writersproblem)是指多个进程对一个共享资源进行读写操作的问题。假设“读者”进程可对共享资源进行读操作,“写者”进程可对共享资源进行写操作;任一时刻“写者”最多只允许一个,而“读者”则允许多个。即对共享资源的读写操作限制关系包括:“读—写,互斥、“写一写”互斥和“读—读”允许。

我们可认为写者之间、写者与第一个读者之间要对共享资源进行互斥访问,而后续读者不需要互斥访问。为此,可设置两个信号量Wmutex、Rmutex和一个公共变量Rcount。其中:Wmutex表示“允许写”,初值是1;公共变量Rcount表示“正在读”的进程数,初值是0;Rmutex表示对Rcount的互斥操作,初值是1。

在这个例子中,我们可见到临界资源访问过程的嵌套使用。在读者算法中,进入区和退出区又分别嵌套了一个临界资源访问过程。

对读者一写者问题,也可采用一般“信号量集”机制来实现。如果我们在前面的读写操作限制上再加一个限制条件:同时读的“读者”最多R个。这时,可设置两个信号量Wmutex和Rcount。其中:Wmutex表示“允许写”,初值是¨Rcount表示“允许读者数目”,初值为R。为采用一般“信号量集”机制来实现的读者一写者算法。

3.4.4 管程

Windows 2000/XP中的进程是系统资源分配的基本单位。Windows 2000/XP进程是作为对象来管理的,可通过相应句柄(handle)来引用进程对象,操作系统提供一组控制进程对象的服务(services)。进程对象的属性包括:进程标识(PID)、资源访问令牌(AccessToken)、进程的基本优先级(BasePriority)和默认亲合处理器集合(ProcessorAffinity)等。

为了支持Win32、OS/2、POSIX等多种运行环境子系统,Windows 2000/XP核心的进程之间没有任何关系(包括父子关系),各运行环境子系统分别建立、维护和表达各自的进程关系。例如,POSIX环境子系统维护POSIX应用进程间的父子关系。如图3-6所示,Windows NT和Windows 2000/XP把Win32环境子系统设计成整个系统的主子系统,一些基本的进程管理功能被放置在Win32子系统中,POSIX和OS/2等其他的子系统会利用Win32子系统的功能来实现自身的功能。在Windows 2000/XP中,与一个运行环境子系统中的应用进程相关的进程控制块信息会分布在本运行环境子系统、Win32子系统和系统内核中。

3.4.5 Windows 2000/XP的进程互斥和同步

在Windows 2000/XP中提供了互斥对象、信号量对象和事件对象三种同步对象和相应的系统调用,用于进程和线程的同步。这些同步对象都有一个用户指定的对象名称,不同进程中用同样的对象名称来创建或打开对象,从而获得该对象在本进程的句柄。从本质上讲,这组同步对象的功能是相同的,它们的区别在于适用场合和效率会有所不同。

互斥对象(Mutex)就是互斥信号量,在一个时刻只能被一个线程使用。它的相关APl包括:CreateMutexi OpenMutex和ReleaseMutex。CreateMutex创建一个互斥对象,返回对象句柄;OpenMutex打开并返回一个已存在的互斥对象句柄,用于后续访问;而ReleaseMutex释放对互斥对象的占用,使之成为可用。 

信号量对象(Semaphore)就是资源信号量,初始值的取值在0到指定最大值之间,用于限制并发访问的线程数。它的相关APl包括:CreateSemaphore、OpenSemaphore和ReleaseSemaphore。CreateSemaphore创建一个信号量对象,在输人参数中指定最大值和初值,返回对象句柄;OpenSemaphore返回一个已存在的信号量对象句柄,用于后续访问;ReleaseSemaphore释放对信号量对象的占用。

事件对象(Event)相当于“触发器”,可用于通知一个或多个线程某事件的出现。它的相关APl包括:CreateEvent、OpenEvent、SetEvent、ResetEvent和PulseEvent。CreateEvent创建一个事件对象,返回对象句柄;OpenEvent返回一个已存在的事件对象句柄,用于后续访问;SetEvent和PulseEvent设置指定事件对象为可用状态;ResetEvent设置指定事件对象为不可用状态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值