首页 > 代码库 > 5,内核同步
5,内核同步
- 内核抢占
- 无论在抢占还是非抢占内核中,运行在内核态的进程都可以自动放弃CPU.称为计划性进程切换.但是,抢占式内核在相应引起进程切换的异步事件的方式上有差异,称为强制性进程切换.
- 抢占式内核的特点: 一个在内核态运行的进程,可能在执行内核函数期间被另一个进程取代.可抢占式的目的是减少用户态进程的分派延迟(即从进程变为可执行状态到它实际开始运行之间的间隔).但是它会引起不容忽视的开销.
- 只有当内核正在执行异常处理程序,且内核抢占没有被显示禁止时,才可能抢占内核.同时本地CPU必须打开本地中断.
- 需要同步的情况: 当计算的结果依赖于两个或以上的交叉内核控制路径的嵌套方式时,可能出现竞争条件.临界区是一段代码,在其他的内核控制路径能够进入临界区前,进入临界区的内核控制路径必须全部执行完这段代码. 必须确保在任意时刻只有一个内核控制路径处于临界区.
- 不需要同步的:1)中断处理程序和tasklet不必编写成可重入函数; 2)仅被软中断和tasklet访问的每CPU变量不需要同步; 3)仅被一种tasklet访问的数据结构不需要同步.
- 每CPU变量:最好的同步技术是吧设计不需要同步的内核放在首位.因为显式的同步原语都有性能开销. 吧内核变量声明为每CPU 变量.
- 仅当确定在系统的CPU上的数据在逻辑上是独立的时候才使用.
- 主要是数据结构的数组,每个CPU对应数组的一个元素.在主存中被排列以使每个数据结构存放在Cache的不同行.所以,并发访问不会引起Cache行的切用和失效
- 对来自不同CPU的并发访问提供保护,但是对来自异步函数的访问不提供保护.
- 原则:内核控制路径应该在禁用抢占的情况下访问每CPU变量.
- 原子操作:
- 若干汇编指令具有"读-修改-写"类型.即访问存储器单元两次,一次读,一次写.
- 确保这样的操作在芯片级是原子的.任何这样的操作都必须以单个指令执行.
- 优化和内存屏障
- 使用优化的编译器时,指令不会严格按照他们在源代码中出现的顺序执行.此外,CPU通常并行地执行若干条指令,且可能重新安排内存访问.
- 但是在处理同步时,必须避免指令重新排序.所以,所有的同步原语起优化和内存屏障的作用.
- 优化屏障:保证编译程序不会混淆放在原语操作之前和之后的汇编指令.但并不保证不使当前CPU把汇编指令混在一起执行.
- 内存屏障:在原语执行之前,原语之前的操作已经完成,类似于防火墙.
- 自旋锁
- 加锁技术:当内核控制路径必须访问共享数据结构或进入临界区时,就需要为自己获取一把"锁".
- 自旋锁用在多CPU下.如果锁开着,就获取锁并继续自己的执行.相反,当锁由运行在另一CPU上的内核控制"锁着"时,就在周围"旋转"反复执行一条紧凑的循环指令(忙等).直到锁被释放.
- 在自旋锁忙等时,内核抢占还是有效的.等待自旋锁释放的进程有可能被更高优先级的进程替代.
- 读写自旋锁
- 为了增加内核的并发能力.在没有写的情况下,允许并发的读操作.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。