完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
linux系统中出现并发与竞态
相关概念: 并发:多个执行单元(进程和中断)同时发生 竞态:多个执行单元对共享资源的同时访问所形成的竞争的状态 共享资源:比如软件上的全局变量,或者是硬件资源 可重入内核:所有的UNIX内核都是可重入的,这意味着若干个进程可以同时在内核态下执行。当然,在单处理器系统上只有一个进程在真正运行,但是有许多进程可能在等待CPU或某一I/O操作完成时再内核态下被阻塞。提供可重入的一种方式是编写函数,在这些函数中只能修改局部变量,而不能改变全局变量,这样的函数叫可重入函数。但是可重入内核,不仅仅局限于这样的可重入函数(尽管一些实时内核正是如此实现的)。相反,可重入内核可以包含非重入函数,并且利用锁机制保证一次只有一个进程执行一个非重入函数。摘自——《深入理解linux内核》第三版 临界区:对共享资源访问的代码区域。 互斥访问:当一个执行单元在访问临界区时,其他执行单元禁止访问临界区,直到访问临界区任务结束。 执行路径具有原子性:当某个任务获取到CPU资源访问临界区时,不允许发生CPU资源的切换,要保证这个任务能够顺利访问临界区,而其他任务等待。 四种情形: 多个CPU核之间的竞争:比如对共享资源(内存,GPIO等)的抢占 同一个CPU上进程与进程之间对共享资源的抢占 中断与进程之间(硬中断与软中断) 中断与中断之间 图形说明描述如下 linux内核解决竞态引起的异常的方法:即同步方法 中断屏蔽 概念 这是在单处理器系统上的常用的一种同步机制:在进入临界区之前禁止所有的硬件中断,离开时再重新启用中断。这种机制尽管简单,但远不是最佳的。因为如果临界区比较大,那么在一个相对较长的时间内持续禁止中断就可能使所有的硬件活动处于冻结状态。 确保一组内核语句被当作一个临界区处理的主要机制之一就是 中断禁止。即使当硬件设备产生了一个IRQ信号时,中断禁止也让内核控制路径继续执行,因此,这就提供了一种有效的方式,确保中断处理程序访问的数据结构也受到保护。然而,禁止本地中断并不保护运行在另一个CPU上的中断处理程序对数据结构的并发访问,因此,在多处理器系统上,禁止本地中断经常与自旋锁结合使用。 特点 能够解决进程与进程之间的抢占引起的异常(进程之间的抢占本身基于软中断实现) 能够解决中断和进程的抢占引起的异常 能够解决中断和中断引起的异常 无法解决多核CPU引起的异常 中断屏蔽保护的临界区的代码执行速度要越快越好,更不能进行休眠操作。因为 linux 系统的很多机制跟中断密切相关(tasklet,软件定时器,硬件定时器等)长时间的屏蔽中断非常危险。 中断屏蔽的编程步骤 注意:屏蔽中断和恢复中断务必要逻辑上成对使用 中断可以以嵌套的方式执行,所以内核不必知道当前控制路径被执行之前IF禁止位的值是什么。在这种情况下,控制路径必须保存先前赋给该标志位上的值,并在执行结束时恢复它。摘自——《深入理解linux内核》第三版 中断屏蔽相关宏函数 功能:宏 local_irq_disable()使用cli汇编语言指令关闭本地CPU上的中断。汇编语言指令cli设置eflags控制寄存器的IF标志。 使用sti汇编语言指令打开本地CPU上被关闭的中断。汇编语言指令sti设置eflags控制寄存器的IF标志。 先把eflags寄存器的内容拷贝到一个局部变量中,随后使用cli汇编指令将IF禁止位置1,关闭中断。 功能:宏 local_irq_restore(flags)恢复eflags原来的的内容。 应用实例 使用中断屏蔽解决LED灯被多个进程访问所引发的竞态问题,见下图 自旋锁 概念 一种广泛应用的同步技术是加锁(locking)。当内核控制路径必须访问共享数据结构或进入临界区时,就需要为自己获取一把“锁”。锁机制保护的资源非常类似于限制在房间内的资源,当某人进入房间时,就把门锁上。如果内核控制路径希望访问资源,就试图获取钥匙“打开门”。当且仅当资源空闲时,它才能成功。然后,只要它还想使用这个资源,门就依然锁着。当内核控制路径释放了锁时,门就被打开,另一个内核控制路径就可以进入房间。如下图 上图显示了锁的使用。5个内核控制路径(P0,P1,P2,P3和P4)试图访问两个临界区(C1和C2)。内核控制路径P0正在C1中,而P2和P4正等待进入C1。同时,P1正在C2中,而P3正在等待进入C2。注意P0和P1可以并行运行。临界区C3的锁现在大开着,因为没有内核控制路径需要进入C3。 自旋锁(spin lock)是用来在多处理器环境中工作的一种特殊的锁。如果内核控制路径发现自旋锁“开着”,就获取锁并继续自己的执行。相反,如果内核控制路径发现锁由运行在另一个CPU上的内核控制路径“锁着”,就在周围“旋转”,反复执行一条紧凑的循环指令,直到锁被释放。 自旋锁的循环指令表示“忙等“。即使等待的内核控制路径无事可做(除了浪费时间),它也在CPU上保持运行。不过,自旋锁通常非常方便,因为很多内核资源只锁1毫秒的时间片段;所以说,释放CPU和随后又获得CPU都不会消耗多少时间。 一般来说,由自旋锁所保护的每个临界区都是禁止内核抢占的。在单处理器系统上,这种锁本身并不起锁的作用,自旋锁原语仅仅是禁止或启用内核抢占。注意:在自旋锁忙等期间,内核抢占还是有效的,因此,等待自旋锁释放的进程有可能被更高优先级的进程替代。 特点 自旋锁能够解决多核引起的竞态问题 自旋锁能够解决进程与进程之前的抢占引起的竞态问题 自旋锁无法解决中断引起的竞态问题 自旋锁保护的临界区的代码执行速度要快,更不能进行休眠操作 没有获取自旋锁的任务将会原地忙等待(原地空转) 利用自旋锁同步的编程步骤 注意:获取自旋锁和释放自旋锁务必要逻辑上成对使用 自旋锁相关定义和配套宏函数 spinlock_t 在linux内核中,每个自旋锁都用spinlock_t结构体来表示,其中包含两个字段: slock 该字段表示自旋锁的状态:值为1表示“未加锁”状态,而任何负数和0都表示“加锁”状态。 break_lock 表示进程正在忙等自旋锁(只在内核支持SMP和内核抢占的情况下使用)。 |
|
|
|
只有小组成员才能发言,加入小组>>
3124个成员聚集在这个小组
加入小组2915 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
3918 浏览 1 评论
3918 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-24 14:23 , Processed in 0.594204 second(s), Total 43, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号