操作系统(中)

129 阅读4分钟

进程与线程

多线程同步

锁与信号量

互斥与同步的实现和使用,主要的方法有两种:锁和信号量.

可以分为忙等待锁无忙等待锁

忙等待锁:

  • 也被称作 自旋锁
  • 可由Test-and-Set指令(原子指令)实现;
  • 当获取不到锁时,线程会一直while循环.

无等待锁: 没获取到锁时,把当前线程放入到锁的等待队列,然后执行调度程序,把CPU让给其他线程.

信号量

  • 互斥:信号量初值为1;
  • 同步:信号量初值为0;

生产者-消费者问题

image.png

  • ⽣产者在⽣成数据后,放在⼀个缓冲区中;
  • 消费者从缓冲区取出数据处理;
  • 任何时刻,只能有⼀个⽣产者或消费者可以访问缓冲区;

image.png

哲学家就餐问题

要解决死锁问题。 对于互斥访问有限的竞争问题(如 I/O 设备)⼀类的建模过程⼗分有⽤。

image.png

  • 哲学家围在⼀起先思考,思考中途饿了就会想进餐;
  • 哲学家要拿到左右两边的叉⼦才进餐;
  • 吃完后,会把两⽀叉⼦放回原处,继续思考;

方案一: 让偶数编号的哲学家「先拿左边的叉⼦后拿右边的叉⼦」,奇数编号的哲学家「先拿右边的叉⼦后拿左边的叉⼦」。

image.png

读者-写者问题

为数据库的访问建立了模型.

  • 读-读允许:同⼀时刻,允许多个读者同时读
  • 读-写互斥:没有写者时读者才能读,没有读者时写者才能写
  • 写-写互斥:没有其他写者时,写者才能写

方案:

image.png

死锁

死锁只有同时满足以下四个条件才会发生:

互斥

image.png

持有并等待

image.png

不可剥夺

image.png

环路等待

image.png

避免死锁问题的发生

只需要破坏其中一个条件就可以。

使用资源有序分配法: 破坏环路等待条件。

使线程A和线程B总是以相同的顺序申请⾃⼰想要的资源。

image.png

悲观锁和乐观锁

互斥锁: 加锁失败后,线程会释放CPU,给其他进程。

  • 加锁失败时,会从 用户态 陷入 内核态,让内核帮我们切换线程.
  • 会有两次线索上下文切换的成本:运行->堵塞;堵塞->就绪。
  • 所以,如果被锁住的代码执行时间很短,就应该选自旋锁。

自旋锁:

  • 用户态 完成加锁和解锁。

读写锁:

  • 当写锁没有被线程持有时,多个线程能并发持有读锁;
  • 当写锁被某线程持有后,其他线程获取读锁或写锁的操作会被堵塞。

读优先:

image.png

写优先:

image.png

公平读写锁: 用队列把获取锁的线程排队,不管是写线程还是读线程都按FIFO原则加锁。

悲观锁:

互斥锁,自选锁,读写锁都属于悲观锁。 悲观锁认为并发访问共享资源时,冲突概率高;所以在访问前必须先加锁。

乐观锁:

若冲突概率非常低,可以使用乐观锁。 它的工作方式是,在访问共享资源时,不用先加锁;修改完资源后,再验证这段时间内有无冲突;若没有其他线程修改资源,则操作完成;否则放弃本次操作。

调度算法

进程调度算法

操作系统(上)

页面置换算法

缺页中断

image.png 若第4步找不到空闲的物理页,则需要 页面置换算法

页表项:

image.png

  • 状态位:是否在物理内存中。
  • 访问字段:记录访问次数,供置换算法参考。
  • 修改位:调入内存后,是否被修改过;由于内存中的每一页都在磁盘上保留一份副本,如果没修改过,则置换该页时就不需要将该页写回磁盘。

image.png

最佳页面置换算法(OPT)

置换在未来最长时间不访问的页面。

image.png

不可能实现。衡量其他算法效率用。

先进先出置换算法(FIFO)

image.png

最近最久未使用的置换算法(LRU)

image.png

时钟页面置换算法(Lock)

image.png

最不常用置换算法(LFU)

选择 访问次数 最少的页面并淘汰。

磁盘调度算法

磁盘由盘片,磁道,扇区组成。寻道是最耗时的部分。

以98,183,37,122,14,124,65,67为例:

先来先服务算法

image.png

最短寻道时间优先算法

优先选择离磁头最近的请求。

image.png

扫描算法SCAN

磁头在一个方向上移动,直到到达该方向最后的磁道,才调头。

image.png

循环扫描算法C-SCAN

掉头时迅速回到最边缘磁道,且该过程不响应请求。

image.png

LOOK与C-LOOK算法

针对SCAN算法的优化叫LOOK算法;针对C-SCAN算法的优化叫C-LOOK算法;仅仅移动到最远的请求位置,然后立即反向移动。