实验五:设备驱动中的并发控制.docVIP

  1. 1、本文档共10页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
实验五:设备驱动中的并发控制.doc

实验五:设备驱动中的并发控制 1.并发与竞态 并发(concurrency)指的是多个执行单元同时、并行被执行,而并发的执行单元对共享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态(race conditions)。例如,对于globalmem设备,假设一个执行单元A对其写入3000个字符“a”,而另一个执行单元B对其写入4000个字符“b”,第三个执行单元C读取globalmem的所有字符。如果执行单元A、B的写操作如图1所示的顺序执行,执行单元C的读操作不会有问题。但是,如果执行单元A、B如图2所示的顺序执行,而执行单元C又“不合时宜”地读,则会读出3000个“b”。 比图2更复杂、更混乱的并发大量地存在于设备驱动中,只要并发的多个执行单元存在对共享资源的访问,竞态就可能发生。在Linux内核中,主要的竞态发生于如下几种情况。 1.对称多处理器(SMP)的多个CPU SMP是一种紧耦合、共享存储的系统模型,它的特点是多个CPU使用共同的系统总线,因此可访问共同的外设和储存器。 2.单CPU内进程与抢占它的进程 Linux2.6内核支持抢占调度,一个进程在内核执行的时候可能被另一高优先级进程打断,进程与抢占它的进程访问共享资源的情况类似于SMP的多个CPU。 3.中断(硬中断、软中断、Tasklet、底半部)与进程之间 中断可以打断正在执行的进程,如果中断处理程序访问进程正在访问的资源,则竞态也会发生。 此外,中断也有可能被新的更高优先级的中断打断,因此,多个中断之间本身也可能引起并发而导致竞态。 上述并发的发生情况除了SMP是真正的并行以外,其他的都是“宏观并行、微观串行”的,但其引发的实质问题和SMP相似。 解决竞态问题的途径是保证对共享资源的互斥访问,所谓互斥访问是指一个执行单元在访问共享资源的时候,其他的执行单元被禁止访问。 访问共享资源的代码区域称为临界区(critical sections),临界区需要以某种互斥机制加以保护。中断屏蔽、原子操作、自旋锁和信号量等是Linux设备驱动中可采用的互斥途径,下节将讲解信号量是如何实现对资源的互斥访问的。 2.信号量 信号量(semaphore)是用于保护临界区的一种常用方法。只有得到信号量的进程才能执行临界区代码,当获取不到信号量时,进程进入休眠等待状态。 Linux系统中与信号量相关的操作主要有如下4种。 1.定义信号量 下列代码定义名称为sem的信号量。 struct semaphore sem; 其中结构体semaphore的定义为: struct semaphore { spinlock_t lock; unsigned int count; struct list_head wait_list; }; 2.初始化信号量 void sema_init (struct semaphore *sem, int val); 该函数初始化信号量,并设置信号量sem的值为val。尽管信号量可以被初始化为大于1的值从而成为一个计数信号量,但是它通常不被这样使用。 void init_MUTEX(struct semaphore *sem); 该函数用于初始化一个用于互斥的信号量,它把信号量sem的值设置为1,等同于sema_init (struct semaphore *sem, 1)。 void init_MUTEX_LOCKED (struct semaphore *sem); 该函数也用于初始化一个信号量,但它把信号量sem的值设置为0,等同于sema_init(struct semaphore *sem, 0)。 此外,下面两个宏是定义并初始化信号量的“快捷方式”。 DECLARE_MUTEX(name) DECLARE_MUTEX_LOCKED(name) 前者定义一个名为name的信号量并初始化为1,后者定义一个名为name的信号量并初始化为0。 3.获得信号量 void down(struct semaphore * sem); 该函数用于获得信号量sem,它会导致睡眠,因此不能在中断上下文使用。 int down_interruptible(struct semaphore * sem); 该函数功能与down()类似,不同之处为,因为down()而进入睡眠状态的进程不能被信号打断,而因为down_interruptible()而进入睡眠状态的进程能被信号打断,信号也会导致该函数返回,这时候函数的返回值非0。 int down_trylock(struct semaphore * sem); 该函数尝试获得信号量sem,如果能够立刻获得,它就获得该信号量并返回0,否则,返回非0值。它不会导致调用者睡眠,可以在中断上下文使用。 在

文档评论(0)

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

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

版权声明书
用户编号:5212202040000002

1亿VIP精品文档

相关文档