linux内核的并发与竞态

并发与竞态是指多个任务单元同时访问同一个资源,就会出现并发,竞态的现象。

其中多个任务单元包括中断,进程/线程,甚至多个多处理器;同一资源既包含硬件资源,也包括软件数据,比如:gpio,硬件设备... ...,软件包括全局变量等。

并发与竞态在内核的设计和驱动的设计都是非常重要的一个模块,因为当多个任务单元同时访问同一资源时,势必会造成某个数据单元的数据的异步,也就是访问错误的数据,如果放问的是指针,则甚至有可能导致系统的崩溃(访问非法内存),而造成这种结果的原因则是访问同一资源时,是并行访问,我们要解决这个问题,就必须将这种并行访问,认为的转化为串行访问,也就是当一个任务单元获取该资源时,其他的任务单元就不能访问该资源,要想访问必须等待拥有资源者将资源释放掉。

对于解决这个问题,内核提供了2个最主要的机制:信号量,自旋锁。另外还有其他的一些衍生机制,其功能都是相同的,只不过用在特定的条件下,不具有通用使用的价值,我们可以暂且了解一下,等到我们经验足够的时候,再去深入的学习。

内核编程模型通常都是结构体数据 + 对应的函数,这也是为什么底层编程的代码量少,并且内核源代码一般也都有现成的例子,我们也可以画瓢。

信号量:数据类型semaphore_t , 对应的函数则是down, up函数也就是我们常说的pv模型,p对应的就是down, v对应up函数。实际上信号量就是一个计数器,我们执行down函数的时候,信号量减1,也表示该当前任务单元获取了该资源,当sem等于0,或者小于0,则其他人物单元不能获取该资源;而执行up函数的时候正好与down函数相反,sem增加1,表示资源可以被其他任务单元获取到。

自旋锁:当信号量初始化为1的时候表示自旋锁,这也是内核中的常用手法,表示资源只能被一个任务单元获取。由于信号量允许任务单元休眠,所以,信号量只能工作在进程上下文中,不能工作在中断上下文。自旋锁也是内核设计中的一个非常有力的解决并发与竞态的手段。

自旋锁:编程模型与信号量相似,也是初始化,获取锁,释放锁,销毁锁。

自旋锁对应的数据类型:spinlock_t, 对应的函数spin_lock, spin_unlock函数,当然了还有init函数和destory函数,执行spin_lock函数则是获取到资源,而其他的任务单原则是不能再对该资源访问,只有执行过spin_unlock函数之后才表示资源可以被其他的任务单元获取,当然,如果当一个任务单元去访问该资源时,正好这个资源已经被其他的人物单元霸占着,那么在门口的这个人物单元只能在门前溜达,就好像我们等人一样,原地打转消磨时间,这也正是自旋锁,自旋的两个字的由来。

其实与并发竞态伴随的还有一个就是临界区,所谓临界区就是共享资源前后的代码,具体多大的范围,全靠程序员自己定,不过一般,都是紧挨着共享资源的代码作为临界区。

死锁是解决并发竞态时,因程序构思或者代码书写不规范等原因,造成死锁现象,在计算机上则表示为程序挂起。

具体死锁的一些特点和如何避免死锁,后边再说

出了上述两种普遍的解决方法,其实还有原子量,位操作,顺序锁。。。 。。。


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值