并发是指多个执行单元同时、并行执行,而并发的执行单元对共享资源(硬件资源和软件上的全局变量、静态变量等)的访问 则很容易导致竞态。对于多核系统,很容易理解,由于多个CPU同时执行,多个CPU同时读、写共享资源时很容易造成竞态。 对于单核系统(例如我们的i.mx6ull),属于“宏观并行,微观串行”,虽然没有真正的“并行”执行, 但是linux系统是多任务系统,linux2.6以及更高版本的内核是抢占式内核,高优先级的任务可以打断低优先级的任务, 再加上中断的存在在单核系统中同样存在竞态的问题。
1. 竞态的产生
竞态的定义是在并发的执行单元对共享资源(硬件资源和软件上的全局变量、静态变量等)的访问。 对应到我们的linux系统就是多个线程对于共享资源的相互竞争访问,而不是按照一定的顺序访问;从而造成不可控的错误, 从竞态的定义可知,竞态产生需要两个条件,第一,存在共享资源,第二,对于共享资源进行竞争访问。
在linux系统中可被多个线程访问的内容都可被称为共享资源,比如一个文件、一块内存、全局变量。 linux系统中一切皆文件,我们编写的驱动在系统中对应一个设备节点文件,从应用程序角度看,驱动也是共享资源。 竞争访问对于单核linux系统主要表现为抢占式内核以及中断。linux2.6及更高版本引入了抢占式内核, 高优先级的任务可以打断低优先级的任务。在线程访问共享资源的时候,另一个线程打断了现在正在访问共享资源的线程同时也对共享 资源进行操作,从宏观角度上来看两个线程对共享资源的访问是“同时”的,存在着竞争关系, 同样也存在线程和中断的“同时”访问共享资源的情况。
举例1
从C语言变量访问的角度来理解竞态的产生过程,代码如下: