面试官让你讲讲Linux内核的竞争与并发,你该如何回答?
内核中的并发和竞争简介??在早期的 Linux内核中 , 并发的来源相对较少 。 早期内核不支持对称多处理( symmetric multi processing,SMP) , 因此 , 导致并发执行的唯一原因是对硬件中断的服务 。 这种情况处理起来较为简单 , 但并不适用于为获得更好的性能而使用更多处理器且强调快速响应事件的系统 。
??为了响应现代硬件和应用程序的需求 ,Linux内核已经发展到同时处理更多事情的时代 。 Linux系统是个多任务操作系统 , 会存在多个任务同时访问同一片内存区域的情况 , 这些任务可能会相互覆盖这段内存中的数据 , 造成内存数据混乱 。 针对这个问题必须要做处理 , 严重的话可能会导致系统崩溃 。 现在的 Linux系统并发产生的原因很复杂 , 总结一下有下面几个主要原因:
- 多线程并发访问 ,Linux是多任务(线程)的系统 , 所以多线程访问是最基本的原因 。
- 抢占式并发访问 , 内核代码是可抢占的 , 因此 , 我们的驱动程序代码可能在任何时候丢失对处理器的独占
- 中断程序并发访问 , 设备中断是异步事件 , 也会导致代码的并发执行 。
- SMP(多核)核间并发访问 , 现在ARM架构的多核SOC很常见 , 多核CPU存在核间并发访问 。 正在运行的多个用户空间进程可能以一种令人惊讶的组合方式访问我们的代码 , SMP系统甚至可在不同的处理器上同时执行我们的代码 。
??如何防止我们的数据被并发访问呢?这个时候就要建立一种保护机制 , 下面介绍几种内核提供的几种并发和竞争的处理方法 。
原子操作原子操作简介??原子 , 在早接触到是在化学概念中 。 原子指化学反应不可再分的基本微粒 。 同样的 , 在内核中所说的原子操作表示这一个访问是一个步骤 , 必须一次性执行完 , 不能被打断 , 不能再进行拆分 。??例如 , 在多线程访问中 , 我们的线程一对a进行赋值操作 , a=1 , 线程二也对a进行赋值操作a=2 , 我们理想的执行顺序是线程一先执行 , 线程二再执行 。 但是很有可能在线程一执行的时候被其他操作打断 , 使得线程一最后的执行结果变为a=2 。 要解决这个问题 , 必须保证我们的线程一在对数据访问的过程中不能被其他的操作打断 , 一次性执行完成 。
整型原子操作函数
文章插图
注:64位的整型原子操作只是将“atomic_”前缀换成“atomic64_” , 将int换成long long 。
位原子操作函数
文章插图
原子操作例程
/* 定义原子变量 , 初值为1*/static atomic_t xxx_available = ATOMIC_INIT(1); static int xxx_open(struct inode *inode, struct file *filp){ ... /* 通过判断原子变量的值来检查LED有没有被别的应用使用 */ if (!atomic_dec_and_test( /* LED被使用 , 返回忙*/ return - EBUSY;}.../* 成功 */ return 0;static int xxx_release(struct inode *inode, struct file *filp){ /* 关闭驱动文件的时候释放原子变量 */ atomic_inc(return 0;}
自旋锁??上面我们介绍了原子变量 , 从它的操作函数可以看出 , 原子操作只能针对整型变量或者位 。 假如我们有一个结构体变量需要被线程A所访问 , 在线程A访问期间不能被其他线程访问 , 这怎么办呢?自旋锁就可以完成对结构体变量的保护 。
推荐阅读
- 120Hz高刷+300Hz触控报点 iQOO 7让你尽享丝滑
- 微信还能这么用?让你大开眼界的微信隐藏操作
- 智能水表Pleco将亮相CES:让你全面掌控家庭用水情况
- Honk:让你聊天时不用等待对方回应了
- 千元SKG颈椎按摩仪来了!“九指神器”让你放松
- 牙刷|用电动牙刷的原因有很多,你是什么原因?
- 心灵上的垃圾也需要清理,这六条能不能帮到你,让你不再浮躁
- 功率|充电器太多让你心烦?倍思帮你解决这些烦恼
- 性能还是相机?这四款四千元价位的手机让你两者兼得
- 性能、拍照超“能打”的一加8T 让你把钱全都花在刀刃上