现代操作系统总结

进程与线程

进程间通信

为了避免竞争,一般需要满足以下4个条件:

  1. 任何两个进程不能同时处于其临界区
  2. 不应该对CPU的速度和数量做任何假设
  3. 临界区外运行的进程不得阻塞其他进程
  4. 不得使进程无限期等待进入临界区

屏蔽中断对操作系统来说是一项很有用的技术,但是对于用户进程则不是一种合适的通用互斥机制(其他CPU核仍然可以访问)


互斥量与信号量区别:

  1. 互斥量用于线程的互斥,信号量用于线程的同步。
    • 这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
    • 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
    • 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
    • note:信号量可以用来实现互斥量的功能
  2. 互斥量值只能为0/1,信号量值可以为非负整数。
    • 也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量时,也可以完成一个资源的互斥访问。
  3. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到
  4. 信号量可以在中断中释放,但是不能在中断中接收。互斥量不能在中断中(会挂起中断)

优先级反转相关:

  1. 本质上,一般意义的信号量和互斥量都会导致优先级反转:
    1. 低优先级进程进入临界区,加锁,执行临界区代码。此时若高优先级进程获取该锁,则会使得一直在忙等待,从而导致优先级反转
  2. 在某些RTOS中,为保证实时性,会将互斥量中加入优先级继承算法,防止优先级反转(如:RT-Thread)

优先级翻转:

当一个高优先级线程试图通过信号量机制访问共享资源时,如果该信号量已被一低优先级线程持有,而这个低优先级线程在运行过程中可能又被其它一些中等优先级的线程抢占,因此造成高优先级线程被许多具有较低优先级的线程阻塞,实时性难以得到保证。

如下图所示:有优先级为 A、B 和 C 的三个线程,优先级 A> B > C。线程 A,B 处于挂起状态,等待某一事件触发,线程 C 正在运行,此时线程 C 开始使用某一共享资源 M。在使用过程中,线程 A 等待的事件到来,线程 A 转为就绪态,因为它比线程 C 优先级高,所以立即执行。但是当线程 A 要使用共享资源 M 时,由于其正在被线程 C 使用,因此线程 A 被挂起切换到线程 C 运行。如果此时线程 B 等待的事件到来,则线程 B 转为就绪态。由于线程 B 的优先级比线程 C 高,因此线程 B 开始运行,直到其运行完毕,线程 C 才开始运行。只有当线程 C 释放共享资源 M 后,线程 A 才得以执行。在这种情况下,优先级发生了翻转:线程 B 先于线程 A 运行。这样便不能保证高优先级线程的响应时间。

优先级反转 (M 为信号量)

在 RT-Thread 操作系统中,互斥量可以解决优先级翻转问题,实现的是优先级继承算法。优先级继承是通过在线程 A 尝试获取共享资源而被挂起的期间内,将线程 C 的优先级提升到线程 A 的优先级别,从而解决优先级翻转引起的问题。这样能够防止 C(间接地防止 A)被 B 抢占。

如下图所示,优先级继承是指,提高某个占有某种资源的低优先级线程的优先级,使之与所有等待该资源的线程中优先级最高的那个线程的优先级相等,然后执行,而当这个低优先级线程释放该资源时,优先级重新回到初始设定。因此,继承优先级的线程避免了系统资源被任何中间优先级的线程抢占

优先级继承 (M 为互斥量)