什么是并发: 并发是指多个执行任务同时、并行被执行。
并发与并行是不一样的,并发就是常见的进程一个CPU多发,并行就是多处理器那样。
什么是竞态: 字面意思是竞争,并发的执行单元对共享资源(硬件资源和软件上的全局变量,静态变量等)的访问容易发生竞态。
并发4个原因:中断,睡眠,多处理,抢占。
Linux设备驱动中常见的互斥机制有以下方式:中断屏蔽、原子操作、互斥锁和信号量等。
信号量(semaphore) 是一种更高级的同步机制,mutex(互斥锁) 可以说是 semaphore(信号量) 在仅取值0/1时的特例。Semaphore可以有更多的取值空间,用来实现更加复杂的同步,而不单单是线程间互斥。我觉得讲的非常好。信号量用于保护临界区的常用方法与自旋锁类似,但不同的是当获取不到信号量时,进程不会原地打转而是进入休眠等待状态。也就是说普通锁被归纳为信号量里面了。
互斥锁和互斥量 在我的理解里没啥区别,不同叫法。广义上讲可以值所有实现互斥作用的同步机制。狭义上讲指的就是mutex这种特定的二元锁机制。互斥锁的作用就是互斥,mutual exclusive,是用来保护临界区(critical section)的 。自旋锁不休眠,意味着它能很快的获得锁了。
所有的一切就是为了避免竞态。就是为了占坑。
如果内核控制路径发现自旋锁“开着”(可以获取,或者说,一个临界区的锁开着代表没人用),就获取锁并继续自己的执行。相反,如果内核控制路径发现锁由运行在另一个CPU上的内核控制路径“锁着”,就在原地“旋转”->反复执行一条紧凑的循环检测指令,进程在CPU上保持运行, 直到锁被释放,才真正执行下一步动作。不过,自旋锁通常非常轻便,因为很多内核资源只锁1毫秒的时间片段,所以等待自旋锁的释放不会消耗太多CPU的时间。
那么自旋锁就有如下几个用途:占用临界区、保证原子性,忙等待不回去节省资源。自旋锁的实现是为了保护一段短小的临界区操作代码,保证这个临界区的操作是原子的,从而避免并发的竞争冒险。在Linux内核中,自旋锁通常用于包含内核数据结构的操作,很多内核代码都是要求原子性的,从这个方面讲,它又可以起到保护临界区的作用。其实,原子性与临界区是等价的。
自旋锁最初就是为了SMP系统设计的,实现在多处理器情况下保护临界区。只有在SMP系统中的自旋锁才需要真正“自旋”。在早期的Linux内核中,并发源相对较少。内核不支持对称多处理器(SMP)系统,唯一导致并发问题的原因是中断。
自旋锁在单CPU不仅无效而且有害,设想普通情况下也就是smp下自旋锁的工作情况:
cpu1持有锁,访问临界区……
cpu2尝试上锁而不得,于是cpu2持续“自旋”,不停的检测锁状态……
cpu1访问结束,释放锁;
cpu2检测到锁状态改变,持有锁,访问临界区……
上面就是一个完整的自旋锁竞争流程。期间,两个cpu都没闲着,尤其是后来的那个cpu2,持续检测锁状态。
那么,设想此情况发生在单cpu系统上,第一个上下文持有锁之后莫名其妙的丢掉了cpu的控制权,转移到了另外一个上下文,又尝试获取该锁,好了至此,cpu彻底被搞死了。因为当前上下文独霸cpu不停的检测锁状态尝试获取该锁,而真正有能力释放该锁的上下文完全得不到机会继续执行来释放它。
每日小常识:
对称多处理器结构 (SMP : Symmetric Multi-Processor),有许多紧耦合多处理器,在这样的系统中,所有的CPU共享全部资源,如总线,内存和I/O系统等,操作系统或管理数据库的复本只有一个,这种系统有一个最大的特点就是共享所有资源。多个CPU之间没有区别,平等地访问内存、外设、一个操作系统。操作系统管理着一个队列,每个处理器依次处理队列中的进程。如果两个处理器同时请求访问一个资源(例如同一段内存地址),由硬件、软件的锁机制去解决资源争用问题。

SMP 服务器的主要特征是共享,系统中所有资源 (CPU 、内存、 I/O 等 ) 都是共享的。也正是由于这种特征,导致了 SMP 服务器的主要问题,那就是它的扩展能力非常有限。对于 SMP 服务器而言,每一个共享的环节都可能造成 SMP 服务器扩展时的瓶颈,而最受限制的则是内存。由于每个 CPU 必须通过相同的内存总线访问相同的内存资源,因此随着 CPU 数量的增加,内存访问冲突将迅速增加,最终会造成 CPU 资源的浪费,使 CPU 性能的有效性大大降低。实验证明, SMP 服务器 CPU 利用率最好的情况是 2 至 4 个 CPU 。物理上的并发说的就是SMP。
NUMA 服务器的基本特征是具有多个 CPU 模块,每个 CPU 模块由多个 CPU( 如 4 个 ) 组成,并且具有独立的本地内存、 I/O 槽口等。由于其节点之间可以通过互联模块 ( 如称为 Crossbar Switch) 进行连接和信息交互,因此每个 CPU 可以访问整个系统的内存 ( 这是 NUMA 系统与 MPP 系统的重要差别 ) 。显然,访问本地内存的速度将远远高于访问远地内存 ( 系统内其它节点的内存 ) 的速度,这也是非一致存储访问 NUMA 的由来。由于这个特点,为了更好地发挥系统性能,开发应用程序时需要尽量减少不同 CPU 模块之间的信息交互。
本文深入探讨了并发控制的概念,包括并发与并行的区别,竞态条件的产生,以及Linux设备驱动中常用的互斥机制,如中断屏蔽、原子操作、互斥锁和信号量等。特别介绍了自旋锁的工作原理及其在SMP系统中的应用,强调了其在保护临界区、保证原子性和避免竞态条件中的作用。

1170

被折叠的 条评论
为什么被折叠?



