Linux Concurrency and Race Conditions

发布于:2023-01-10 ⋅ 阅读:(440) ⋅ 点赞:(0)
  1. Concurrency and Race Conditions-Why introduce?

 

Linux内核早期结构中,跟并发相关的资源有限,并未将SMP Symmetric

multiprocessing system)考虑进来。而在当时唯一能够产生并发的是硬件中断服务,内核对于此种场景一种极为简单的方式(进入临界区域后关闭掉中断,退出后重新打开),但此种方式不再适用于当今多核多线程多中断的场景,因此内核也得与时俱进,到今天提供了一系列跟并发有关系的API接口,可以应用在不同的平台上。

LDD3中关于 Concurrency and Race Conditions的背景交代的很清楚,大概就是说当前多内核,多线程,且单内核支持抢占和中断的现代环境下,程序运行过程中不可避免的会发生资源的并发访问并从而产生竞赛,如果内核作为整个系统的“大管家”不加以治理和疏通,情况将是灾难性的,继续贴图来说明这种“race”有多激烈:

多核多线程多中断的场景下,并发并不局限的存在于单个内核中,内核间也有并发的存在,总结下来:

 
进程时间片耗完,轮到其他进程执行;
进程被高优先级进程抢占;
进程被中断抢占;
中断被高优先级中断抢占;

  SMP多核CPU
核间进程之间;
核间进程与中断之间;
核间中断与中断

在这样一种残酷的竞争下,内核的措施和方案也有条不紊的推出,虽然这些关于并发控制的方案形态各异,适用于不同的场景,但其核心思想从未改变过,这里引用一下经典:making sure that only one thread of execution can manipulate a shared resource at any time.


2.Concurrency and Race Conditions:中断屏蔽,Semaphores,Mutexes,spin_lock and completion

中断屏蔽:

Linux内核当中提供了local_irq_disablelocal_irq_enable来实现中断屏蔽,具体而言,进入到临界区域后所在核内的中断与进程之间的并发不会发生,因为Linux内核的进程调度都依赖于中断来实现。

  但是,由于由于Linux内核的进程调度,异步IO等重要的操作都依赖于中断,在中断屏蔽期间所有的中断都无法得到处理,因此长时间使用中断屏蔽是很危险的,有可能造成数据丢失乃至系统崩溃的结果。另外local_irq_disablelocal_irq_enable只能屏蔽本cpu上的中断响应,对于SMPcpu引发的竞态无能为力,因此在驱动程序中单独使用local_irq_disablelocal_irq_enable通常意味着一个bug

  内核中还提供了local_irq_savelocal_irq_restore,其原理除了禁止中断响应外,还保存目前cpu的中断位信息,临界区结束后恢复中断信息。看得出来, local_irq_savelocal_irq_restore相较于local_irq_disablelocal_irq_enable更具备“人情味儿”,可以在临界区域逗留更长时间,因此前者的组合跟自旋锁(spin_lock)搭配形成的API在内核中很常见。

原子操作:

 

 spin_lock:

 Semaphores​​​​​​​:

 


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章