Linux内核设备驱动-2.pptVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
什么是临界区(critical regions)? 就是访问和操作共享数据、设备的代码段,这段代码必须被原子地执行。这些共享数据、设备也称为临界资源。 什么是竞争状态? 多个内核任务同时访问同一临界区 什么是同步? 避免并发和防止竞争状态称为同步(synchronization) 举例 考虑一个非常简单的共享资源的例子:一个全局整型变量和一个简单的临界区,其中的操作仅仅是将整型变量的值增加1: i++ 该操作可以转化成下面三条机器指令序列: 得到当前变量i的值并拷贝到一个寄存器中 将寄存器中的值加1 把i的新值写回到内存中 内核任务1 内核任务2 获得i(1) --- 增加 i(1-2) --- 写回 i(2) --- 获得 i(2) 增加 i(2-3) 写回 i(3) 当共享资源是一个复杂的数据结构时,竞争状态往往会使该数据结构遭到破坏。 锁机制可以避免竞争状态正如门锁和门一样,门后的房间可想象成一个临界区。 在一个指定时间内,房间里只能有一个内核任务存在,当一个任务进入房间后,它会锁住身后的房门;当它结束对共享数据的操作后,就会走出房间,打开门锁。如果另一个任务在房门上锁时来了,那么它就必须等待房间内的任务出来并打开门锁后,才能进入房间。 任何要访问临界资源的代码首先都需要占住相应的锁,这样该锁就能阻止来自其它内核任务的并发访问: 内核任务调度与同步关系 用户空间的进程运行无需过多考虑需要同步的地方。 在内核空间的内核任务需要考虑同步的原因则增加了。 内核空间中的共享数据对内核中的所有任务可见,所以当在内核中访问数据时,就必须考虑是否会有其他内核任务并发访问的可能、是否会产生竞争条件、是否需要对数据同步。 同步原因 中断 中断几乎可以在任何时刻异步发生,也就可能随时打断当前正在执行的代码。 睡眠 在内核执行的进程可能会睡眠,这就会唤醒调度程序,从而导致调度另一个任务执行。 对称多处理 两个或多个处理器可以同时执行代码。 内核抢占 因为内核具有抢占性,所以内核中的任务可能会被另一任务抢占(在2.6内核引进的新能力)。 后两种情况大大增加了内核任务并发执行的可能性,使得并发随时随刻都有可能发生,而且不可清晰预见,规律难寻。 找出哪些数据需要保护是关键所在 内核任务的局部数据仅仅被它本身访问,显然不需要保护。 如果数据只会被特定的进程访问,也不需加锁 大多数内核数据结构都需要加锁:若有其它内核任务可以访问这些数据,那么就给这些数据加上某种形式的锁;若任何其它东西能看到它,那么就要锁住它。 内核同步措施 为了避免并发,防止竞争。内核提供了一组同步方法来提供对共享数据的保护。 信号量 自旋锁 信号量 Linux中的信号量是一种睡眠锁。 如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。 当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。 信号量的睡眠特性,使得信号量适用于锁会被长时间持有的情况; 信号量的操作 信号量支持两个原子操作P()和V(),前者做测试操作,后者叫做增加操作。 Linux中分别叫做down()和up()。 信号量 down()和up()。 down()操作通过对信号量计数减1来请求获得一个信号量。 如果结果是0或大于0,信号量锁被获得,任务就可以进入临界区了。 如果结果是负数,任务会被放入等待队列,处理器执行其它任务。 相反,当临界区中的操作完成后,up()操作用来释放信号量,增加信号量的计数值。 如果在该信号量上的等待队列不为空,处于队列中等待的任务在被唤醒的同时会获得该信号量。 信号量 信号量 Linux信号量的实现 内核代码必须包含 asm/semaphore.h,才能使用信号量。 相关的类型是 struct semaphore Linux信号量的实现 信号量的声明和初始化 直接创建一个信号量 struct semaphore * sem; 接着使用 sema_init 来初始化这个信号量: void sema_init(struct semaphore *sem, int val); 互斥模式的信号量声明,内核提供宏定义. DECLARE_MUTEX(name); 信号量初始化为 1 DECLARE_MUTEX_LOCKED(name); 信号量初始化为0 Linux信号量的实现 动态分配的互斥信

文档评论(0)

000 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档