操作系统读书笔记(4)

首先,了解和并发有关的关键术语:

原子操作:一个或多个指令的序列,对外不可分割;即没有其他进程可以看见其中间状态或中断此操作

临界区:是一段代码,在这段代码中进程将访问共享资源,当另一个进程已经在这段代码中运行时,这个进程就不能在这段代码中执行

死锁:两个或两个以上的进程因其中的每个进程都在等待其他进程做完某些事情而不能继续执行,这样的情形叫做死锁

活锁:两个或两个以上的进程为了响应其他进程中的变化而持续改变自己的状态但不做有用的工作

互斥:当一个进程在临界区访问共享资源的时候,其他进程不能进入该临界区访问任何共享资源

竞争条件:对个线程或进程在读写一个共享数据时,结果依赖于他们执行的相对时间

饥饿:是指一个可运行的进程尽管能继续执行,但是被调度器无限期的忽略,而不能被调度执行的情况

忙等待:或者自旋等待,是指进程在得到临界区访问权之前,它只能继续执行测试变量的指令来得到访问权,除此之外不能做其他的事情



1、并发的原理

在单处理器多道程序设计系统中,进程交替执行,表现出一种同时执行的外部特征。因为各进程的相对执行速度是不可预测的,这就带来了并发处理的有关问题,就算是一个处理器也有可能产生并发问题。多处理器系统从根本上来说跟单处理器系统中是相同的。操作系统设计技术的基础是并发

操作系统关注:一个进程的功能和输出的结果必须与执行速度无关。


为了理解一个进程的功能与执行速度无关,我们首先应该考虑进程间的交互方式

1).竞争:进程之间不知道的对方的存在,一个进程的结果和其他进程无关。

2).通过共享合作:进程间接知道对方的存在,一个进程的结果可能依赖于从其他进程获得的消息。
3).通过通讯合作:进程直接知道对方的存在(知道对的继承ID),一个进程的结果可能依赖于从其他进程获得的消息。


为了解决进程的并发问题,要提供对进程互斥的支持,一种方法是让并发执行的进程担负这个责任,这类进程不论是系统程序还是应用程序,都需要与另一个进程合作,而不需要程序设计语言或操作系统提供任何支持来实施互斥,这种方法称作软件方法;第二种方法涉及专门的机器指令,适用于单处理器和多处理器上任何数目的进程,支持多个临界区,这种方法可以减少开销,但是也有一些严重的缺点,很难成为一种通用的解决方案;第三种方法是在操作系统或程序设计语言设计中提供某种级别的支持,主要有信号量、管程、消息传递


2、信号量

信号量:用于进程间传递信号的一个整数值。在信号量上只有三种操作可以进行,初始化、递减和增加,这三种操作时原子操作。递减操作可以用来阻塞一个进程,增加操作可以用来解除阻塞一个进程。也称为计数信号量和一般信号量。

二元信号量:只取0值和1值的信号量。

互斥量:类似于二元信号量,关键区别在于为其加锁(设定值为0)的进程和为其解锁(设定为1)的进程必须为同一个进程。


强信号量:不论是计数信号量还是二元信号量,都需要使用队列来保存在信号量上等待的进程。这就产生了进程按照什么策略从队列中移出。使用先进先出的策略定义的信号量称为强信号量,没有规定进程从队列中移出顺序的信号量称为弱信号量。强信号量保证不会饥饿,弱信号量不能。

下面给出了一种使用信号量s解决互斥问题的方法:

/* program mutualexclusion*/
const int n= //进程数;
semaphore s=1;
void P(int i)
{
    while(true)
    {
        semWait(s);
        /*临界区*/
        semSignal(s);
        //其他部分
    }
}

信号量一般初始化为1,第一个执行semWait(接收信号)的进程可以立即进入临界区,并把s置为0。接着任何试图进入临界区的进程都会发现第一个进程忙,因此被阻塞,把s的值置为-1,可以有任意数目的进程试图进入,每个不成功的尝试都会导致s减1,当最初进入临界区的进程离开时,s增加1,(代码中的semWait使信号量减一,semSignal是信号量加一)一个被阻塞的进程(如果有的话)被移出等待队列,并置于就绪状态。这样,当操作系统下一次调度时,它可以进入临界区。

注意:正常进程执行可以并行,但是临界区代码只能串行执行。使用信号量的互斥程序可以很好的解决一次允许多个进程进入临界区的要求。



3、管程

管程:一种编程语言结构,在一个抽象数据类型中封装了变量、访问过程和初始化代码。管程的变量只能由管程自己的访问过程来访问,一个进程可以通过调用管程的一个访问过程进入管程,每次只能有一个进程在其中执行。访问过程即临界区。管程可以有一个等待进程队列。管程提供与信号量一样的功能,但是更易于控制。


在使用信号量的情况下,执行互斥和同步都属于程序员的责任;对于管程,它构造了自己的互斥机制。管程优于信号量之处在于所有的同步机制都被限制在管程内部,不但容易验证同步的正确性,还易于检测出错误。关于管程和信号量的比较可以参看这篇文章:http://blog.csdn.net/justmeh/article/details/5828246

因此,可以把一个共享数据放在管程中,从而提供对它的保护。如果管程中的数据代表某些资源,那么管程为访问这些资源提供了互斥机制。



4、消息传递

进程交互时,必须满足两个基本要求:同步和通信。为了实施互斥,进程需要同步;为了合作,进程间需要交换信息,消息传递是能够提供这些功能的一种方法。消息传递还有一个优点是,它可以在分布式系统、共享内存的多处理器系统和单处理器系统中实现。

消息传递的实际功能是以一对原语的形式提供:

send(desrination,message);发送消息原语

receive(source,message);接受消息原语


下表中列出了与消息传递系统相关的一些设计问题:



下面给出实现互斥的消息传递方式:假设使用阻塞send和无阻塞receive原语,一组并发进程共享一个信箱box,它可供所有进程在发送和接受消息时使用,该信箱被初始化成一个无内容的消息。希望进入临界区的进程首先试图接受一条消息,如果信箱为空,则该进程被阻塞;一旦进程获取消息,它执行它的临界区,然后把该消息放回信箱。因此,消息函数可以看做是在进程之间传递的一个令牌。

const int n=/*进程数*/
void P(int i)
{
    message msg;
    while(true)
    {
        receive(box,msg);
        //临界区
        send(box,msg);
        //其他部分
    }
}
void main()
{
    create mailbox(box);
    send(box,null);
    parbegin(P(1),P(2)...,P(n));
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值