竞态产生
Linux系统找那个存在大量的并发联系,因此会导致可能的竞态;
1. 正在运行的用户空间进程可以以多种组合方式访问我们的代码;
2. SMP系统甚至可以再不同的处理器上同时执行我们的代码;
3. 内核代码是可抢占的,因此,我们的驱动程序代码可能在任何时候丢失对处理器的独占,而拥有处理器的进程可能正在调用我们的驱动程序代码;
4. 设备中断是异步事件,也会导致代码的并发执行;
5. 内核还提供了许多可延迟代码执行的机制,比如workqueue,tasklet以及timer等,这些机制使得代码可在任何时刻执行,而不管当前进程在做什么;
6. 在现代热插拔的世界中,设备可能会在我们正使用时消失;
应对竞态
竞态通常作为对资源的共享访问结果而产生;当两个执行线程需要访问相同的数据结构或者硬件资源时,混合的可能性永远存在;因此在设计自己的驱动程序时,第一个要记住的规则是:只要可能,就应该避免资源的共享;如果没有并发的访问,也就不会有静态的产生;因此,编写内核代码应该具有最少的共享;这种思想最明显的应用就是避免使用全局变量;如果将资源放在多个执行现成都会找到的地方,就需要有足够的理由;
资源共享的硬规则
在单个执行线程之外共享硬件或者软件资源的任何时候,因为另外一个线程可能产生对资源的不一致观察,因此必须显式的管理对该资源的访问;访问管理的常见技术为“锁定”或者“互斥”,以确保一次只有一个执行现成可操作共享资源;
当内核代码创建了一个可能和其他内核部分共享的对象时,该对象必须在还有其他组件引用自己时保存存在并正常工作;这一规则产生下面的两个需求:在对象尚不能正确工作时,不能将其对内核可用,也就是说,对这类对象的应用必须得到跟踪;大多数情况下,内核会为我们处理引用计数,然而总有例外;