进程同步

背景:生产者-消费者问题:并发访和操作同一个数据时的执行结果与访问发生的顺序有关,而进程的同步对操作系统至关重要。

进程并发执行的好处

进程需要与计算机中其他进程或设备进行协作

  1. 共享资源
  2. 加速
    • I/O操作和CPU计算可以并行
    • 程序可划分成多个模块放在多个处理机上并行执行
  3. 模块化
    • 将大程序分解成小程序(gcc会调用 cpp cc1 cc2 as ld)
    • 使系统易于复用和扩展

进程的交互关系

  • 互斥(Mutual Exclusion)
    • 一个进程占用资源 其他进程不能使用
  • 死锁(Deadlock)
    • 多个进程各占用部分资源 形成循环等待
  • 饥饿(Starvation)
    • 其他进程可能轮流占用资源 一个进程一直得不到资源

临界区

临界区问题:字面意思

临界区:当一个进程进入临界区时,没有其他进程可以在临界区内执行。

满足的三项要求:

  • 互斥:不能同时在临界区执行
  • 前进:一定时间内选择进入临界区的进程
  • 有限等待:不能等太久

处理临界区问题的两种方法:字面意思

抢占内核

非抢占内核

软件实现

Peterson 算法:两个进程在临界区与剩余区间交替执行

硬件同步:锁

一个进程进入临界区之前必须得到锁,退出后释放锁

对于单处理器环境,只需要在修改共享变量时禁止中断就行了(非抢占式)

多处理器环境,这种做法会降低效率的,解决方法时原子操作,这就需要硬件上的支持了(锁)

1560164888222

信号量

以上都是基础知识,重点是信号量

1560162864230

信号量的用途很广,比较简单的就是司机乘务员之类的,通过信号量解决各种同步问题(比如实现顺序的先后)。

可以用二进制信号量来解决临界区问题(0和1之间的)

有了信号量之后临界区问题变得简单得多,现在来说说信号量的实现

实现

忙等待:看程序可以知道为进入临界区的进程一直在循环之中,这是多道程序不允许的,这样做会浪费cpu时间

自旋锁:会处于忙等待的信号量

克服忙等:修改PV操作呗

优点:节省cpu时间,提高cpu的利用率,让cpu被其他进程有效的利用

缺点:行下文切换花费时间,如果锁占用时间短,那么会得不偿失

实现:在wait操作时,如果要等待,阻塞自己,这个操作将进程放入与信号量相关的等待队列中,并将进程的状态切换为等待状态,然后指向cpu调度程序,选择另一个进程来执行。

当执行signal()操作之后,通过wakeup操作重新执行该进程,即将状态转换为就绪状态,然后该进程放到就绪队列之中

1560163812160

(S是信号量)

注意block和wakeup之间的对应关系

说了那么多,信号量的关键之处在于他们是原子地执行,这个就是硬件的事儿了

死锁:第七章内容

饥饿:进程在信号量内无限期阻塞(栈)

说了那么多还是同步的问题

好像对于临界区地实现没有过多的关注

线面介绍几个经典的同步问题

经典同步问题

有限缓冲问题:生产者-消费者问题

读者-写者问题:字面意思

1560164384846

哲学家就餐问题:

信号量不能很好的解决这个问题,第七章死锁会讲到

管程:略

总结

实现同步互斥需要解决临界区问题

临界区一般是共享变量地操作

信号量可以实现同步互斥

进程互斥
进程互斥:在多个程序中,有两个进程不可以同时进行(例如读,写操作)。

竞争资源(临界资源)

当并发进程竞争使用同一资源时,他们之间就会发生冲突。如果操作系统将资源分配给其中的某一个进程使用,另一个进程就必须等待,直到申请的资源可用时,由操作系统分配给他们。

如果竞争资源的进程太多,这些进程还必须等待在一个队列中,如就绪队列,阻塞队列等。

一种极端的情况是,被阻塞进程永远得不到申请的资源,而死锁。

采用互斥方式,使用临界资源

资源的互斥,进程使用上述这类资源的时候,只能有一个进程对资源进行处理。(临界区)

进程同步

进程同步是一个操作系统级别的概念,是在多道程序的环境下,存在着不同的制约关系,为了协调这种互相制约的关系,实现资源共享和进程协作,从而避免进程之间的冲突,引入了进程同步。比如说进程A需要从缓冲区读取进程B产生的信息,当缓冲区为空时,进程B因为读取不到信息而被阻塞。而当进程A产生信息放入缓冲区时,进程B才会被唤醒。

同步互斥解决方法(同样是实现临界区地方法):软件、硬件、信号量、管程

-------------本文结束有空来玩-------------
坚持原创技术分享,您的支持将鼓励我继续创作!