设为首页 收藏本站
查看: 931|回复: 0

[经验分享] Linux 设备驱动--- 并发 与 竞态

[复制链接]

尚未签到

发表于 2017-11-18 09:31:35 | 显示全部楼层 |阅读模式
并发:
  多个执行单元同时被执行.
  

竞态:
  并发的执行单元对资源 ( 硬件资源和软件上的全局变量等 ) 的访问导致的竞争状态.

DSC0000.jpg

  

并发的处理:
  处理并发的常用技术是加锁或者互斥,即保证在任何时间只有一个执行单元可以操作共享资源.

  在 Linux 内核中主要通过 semaphore 机制 (信号量)和spin_lock 机制 (自旋锁)实现.

  

原子操作:
定义:
  原子操作指的是在执行过程中不会被别的代码所中断的操作.
  分为 位 和 整型变量 两类原子操作。
  

atomic_t  :



[cpp] view plain copy

  • typedef struct {  
  • volatile int counter;  
  • } atomic_t;
原子操作函数:
整型原子操作:



[cpp] view plain copy

  • void atomic_set(atomic_t *v, int i);   //设置原子变量v的值为i  
  • atomic_t v = ATOMIC_INIT(0);            //定义原子变量v, 并初始化为0  **************************  
  • atomic_read(atomic_t *v);              //获得原子变量的值,返回原子变量的值  
  • void atomic_add(int i, atomic_t *v);    //原子变量+i  
  • void atomic_sub(int i, atomic_t *v);    //原子变量-i  
  • void atomic_inc(atomic_t *v);           //原子变量+1            *******************************  
  • void atomic_dec(atomic_t *v);           //原子变量-1  
  对原子变量执行自增,自减和减操作后 ,测试其是否为0,为 0 则返回 true,否则返回 false :



[cpp] view plain copy

  • int atomic_inc_and_test(atomic_t *v);   
  • int atomic_dec_and_test(atomic_t *v);              ***********************  
  • int atomic_sub_and_test(int i, atomic_t *v);         
  

  对原子变量进行加/减,自增/自减操作,并返回新的值:



[cpp] view plain copy

  • int atomic_add_return(int i, atomic_t *v);  
  • int atomic_sub_return(int i, atomic_t *v);  
  • int atomic_inc_return(atomic_t *v);  
  • int atomic_sub_return(atomic_t *v);  
位原子操作:



[cpp] view plain copy

  • void set_bit(nr, void *addr);    //将addr地址的nr位 置为1  
  • void clear_bit(nr, void *addr);  //将addr地址的nr位 清0  
  • void change_bit(nr, void *addr);  //对addr地址的nr位 反置  
  • int test_bit(nr, void *addr);    //返回addr地址的nr位  
  • int test_and_set_bit(nr, void *addr);  
  • int test_and_clear_bit(nr, void *addr);  
  • int test_and_change_bit(nr, void *addr);  
  • 先设值,后返回。
  

  

实例 --- 原子操作:
1,定义一原子变量:
  在程序开头定义原子变量,初始化为 1 :



[cpp] view plain copy

  • static atomic_t canopen = ATOMIC_INIT(1);     //定义原子变量并初始化为1  
2,在 open 函数里检测原子变量值:
  如果减 一 为 0!true 为 假 ,if 里面的原子变量加一恢复到  0

  • {


  •     atomic_inc(&canopen);
  •     return -EBUSY;  
  • }
3,在退出时 close 函数 恢复原子变量值:
  最后, 在应用程序退出时 close 函数, 自增 恢复原子变量值为 1:



[cpp] view plain copy

  • atomic_inc(&canopen);
4,应用程序测试:
  在应用程序里面打开驱动程序:



[cpp] view plain copy

  • fd = open("/dev/buttons", O_RDWR);  
  • if (fd < 0)  
  • {
  •     printf("can't open!\n");  
  •     return -1;  
  • }
  
当有两个应用程序打开同一这个驱动的时候,打印 can't open! .

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-408151-1-1.html 上篇帖子: Windows到Linux的文件上传、下载 下篇帖子: 如何在linux下判断磁盘是否为raid
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表