关键部分可以在OS中打断吗?如果在用户部分或内核代码中实现会产生什么影响?

问题描述

最近,在一次采访中有人问我这个问题,关于如果我们通过互斥体实现中断时中断所产生的关键部分的影响。如果关键部分以用户代码或内核代码实现,是否会有效果

解决方法

这取决于临界区的范围和临界区的实现。临界区是应用于一段代码的约束,用于阻止对某些共享数据的并发访问。

在单核微控制器上

需要保护以下类型的数据。

  1. 数据仅在多个线程之间共享
  2. 数据仅在多个中断之间共享
  3. 线程和中断之间共享的数据

可以通过以下方式实现临界区

  1. 禁用所有中断(在用户上下文和操作系统内核上下文中可用)
  2. 使用操作系统软件互斥锁(在用户上下文中可用)

对于选项 1,由于操作系统,特别是上下文切换器是使用中断实现的,这也将有效地禁用操作系统上下文切换和临时多线程。这确保只有当前线程或中断上下文可以访问数据。 因此禁用中断是对所有 3 种共享数据的有效保护。 然而,临时禁用中断会增加微控制器的中断延迟和操作系统的调度延迟,因为中断处理程序和操作系统可以响应直到中断被重新启用。

如果数据仅在线程之间共享,则可以选择使用操作系统软件互斥锁来实现临界区。操作系统一次限制一个线程对锁定的互斥锁的访问,如果线程只在获取互斥锁上的锁时访问数据,则对数据的访问受到保护。 OS 软件互斥锁通过 OS 调度保护共享数据,并且在临界区期间 OS 和中断保持完全运行。这种类型的实现不会阻止在临界区处理中断,也不会阻止未受影响线程的调度。

操作系统软件互斥锁不能有效保护线程和中断之间共享的数据,因为操作系统无法通过调度来防止中断。

如果操作系统本身依赖共享数据,或者没有操作系统时,由于操作系统互斥锁尚不可用,通常会看到操作系统代码或裸机代码禁用中断以获得临界区。