第7章设备驱动中的并发_第1页
第7章设备驱动中的并发_第2页
第7章设备驱动中的并发_第3页
第7章设备驱动中的并发_第4页
第7章设备驱动中的并发_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第7 7章章 设备驱动中的并发控制设备驱动中的并发控制现代操作系统有三大特性:中断处理、多任务处理和现代操作系统有三大特性:中断处理、多任务处理和多处理器(多处理器(SMP)。这些特性导致当多个进程、线程或者)。这些特性导致当多个进程、线程或者CPU同时访问一个资源时,可能导致错误,这些错误是操作同时访问一个资源时,可能导致错误,这些错误是操作系统运行所不允许的。在操作系统中,内核需要提供并发控系统运行所不允许的。在操作系统中,内核需要提供并发控制机制,对公用资源进行保护。本章将对保护这些公用资源制机制,对公用资源进行保护。本章将对保护这些公用资源的方法进行简要的介绍。的方法进行简要的介绍。

2、7.1 7.1 并发与竞争并发与竞争并发是指在操作系统中,一个时间段中有几个程序都并发是指在操作系统中,一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。并发容易导致竞争的问题。竞争就是两个或者两个上运行。并发容易导致竞争的问题。竞争就是两个或者两个以上的进程同时访问一个资源,从而引起资源的错误。以上的进程同时访问一个资源,从而引起资源的错误。7.2 7.2 原子变量操作原子变量操作原子变量操作是原子变量操

3、作是Linux中提供的一种简单的同步机制。中提供的一种简单的同步机制。原子变量操作是一种在操作过程中不会被打断的操作,所以原子变量操作是一种在操作过程中不会被打断的操作,所以在内核驱动程序中非常有用。本节对在内核驱动程序中非常有用。本节对Linux中原子变量的操中原子变量的操作进行详细的分析。作进行详细的分析。7.2.1 7.2.1 原子变量操作原子变量操作所谓原子变量操作,就是该操作绝不会在执行完毕前所谓原子变量操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断。也就说,原子变量操作是一种被任何其他任务或事件打断。也就说,原子变量操作是一种不可以被打断的操作。原子操作需要硬件的支持,

4、因此是架不可以被打断的操作。原子操作需要硬件的支持,因此是架构相关的,其构相关的,其API和原子类型的定义都定义在内核源码树的和原子类型的定义都定义在内核源码树的include/asm/atomic.h文件中,它们都使用汇编语言实现,因文件中,它们都使用汇编语言实现,因为为C语言并不能实现这样的操作。语言并不能实现这样的操作。7.2.2 7.2.2 原子整形操作原子整形操作有时候需要共享的资源可能只是一个简单的整形数值。例如有时候需要共享的资源可能只是一个简单的整形数值。例如在驱动程序中,需要对包含一个在驱动程序中,需要对包含一个count的计数器。这个计数器表示的计数器。这个计数器表示有多少

5、个应用程序打开了设备所对应的设备文件。通常在设备驱有多少个应用程序打开了设备所对应的设备文件。通常在设备驱动程序的动程序的open()函数中,将函数中,将count变量加变量加1。在。在close()函数中,将函数中,将count减减1。如果只有一个应用程序执行打开和关闭操作,那么这里。如果只有一个应用程序执行打开和关闭操作,那么这里的的count计数不会出现问题。但是如果有多个应用程序同时打开或计数不会出现问题。但是如果有多个应用程序同时打开或者关闭设备文件,那么就可能导致者关闭设备文件,那么就可能导致count多加或者少加,出现错误多加或者少加,出现错误。为了避免这个问题,内核提供了一个原

6、子整形变量,称为为了避免这个问题,内核提供了一个原子整形变量,称为atomic_t。7.2.3 7.2.3 原子位操作原子位操作除了原子整数操作外,还有原子位操作。原子位操作除了原子整数操作外,还有原子位操作。原子位操作是根据数据的每一位单独进行操作。根据体系结构的不同,是根据数据的每一位单独进行操作。根据体系结构的不同,原子位操作函数的实现也不同。原子位操作函数的实现也不同。7.3 7.3 自旋锁自旋锁自旋锁是一种简单的并发控制机制,其是实现信号量自旋锁是一种简单的并发控制机制,其是实现信号量和完成量的基础。自旋锁对资源有很好的保护作用,在和完成量的基础。自旋锁对资源有很好的保护作用,在Li

7、nux驱动程序中进程使用,本节将对自旋锁进行详细的介驱动程序中进程使用,本节将对自旋锁进行详细的介绍。绍。7.3.1 7.3.1 自旋锁概述自旋锁概述在在Linux中提供了一些锁机制来避免竞争条件,最简单中提供了一些锁机制来避免竞争条件,最简单的一种就是自旋锁。引入锁的机制,是因为单独的原子操作的一种就是自旋锁。引入锁的机制,是因为单独的原子操作不能满足复杂的内核设计需要。例如,当一个临界区域要在不能满足复杂的内核设计需要。例如,当一个临界区域要在多个函数之间来回运行时,原子操作就显得无能无力了。多个函数之间来回运行时,原子操作就显得无能无力了。Linxu中一般可以认为有两种锁,一种是自旋锁,

8、另一中一般可以认为有两种锁,一种是自旋锁,另一种是信号量。这两种锁是为了解决内核中遇到的不同问题开种是信号量。这两种锁是为了解决内核中遇到的不同问题开发的。其实现机制和应用场合有所不同,下文将分别对这两发的。其实现机制和应用场合有所不同,下文将分别对这两种锁机制进行介绍。种锁机制进行介绍。7.3.2 7.3.2 自旋锁的使用自旋锁的使用在在Linux中,自旋锁的类型为中,自旋锁的类型为struct spinlock_t。内核提。内核提供了一系列的函数来对供了一系列的函数来对struct spinlock_t进行操作。下面将对进行操作。下面将对自旋锁的操作方法进行简要的介绍。自旋锁的操作方法进行

9、简要的介绍。1定义和初始化自旋锁定义和初始化自旋锁2锁定自旋锁锁定自旋锁3释放自旋锁释放自旋锁4使用自旋锁使用自旋锁7.3.3 7.3.3 自旋锁的使用注意事项自旋锁的使用注意事项在使用自旋锁时,有几个注意事项需要读者理解,这在使用自旋锁时,有几个注意事项需要读者理解,这几个注意事项是:几个注意事项是:自旋锁是一种忙等待。自旋锁是一种忙等待。自旋锁不能递归使用。自旋锁不能递归使用。7.4 7.4 信号量信号量本节介绍锁的另一种实现机制,这种机制就是本节介绍锁的另一种实现机制,这种机制就是Linux中中常用的信号量。常用的信号量。Linux中提供了两种信号量,一种用于内核中提供了两种信号量,一种

10、用于内核程序中,一种用于应用程序中。由于这里讲解的是内核编程程序中,一种用于应用程序中。由于这里讲解的是内核编程的知识,所以只对内核中的信号量进行详细讲述。的知识,所以只对内核中的信号量进行详细讲述。7.4.1 7.4.1 信号量概述信号量概述和自旋锁一样,信号量也是保护临界资源的一种有用方和自旋锁一样,信号量也是保护临界资源的一种有用方法。信号量与自旋锁的使用方法基本一样。与自旋锁相比,信法。信号量与自旋锁的使用方法基本一样。与自旋锁相比,信号量只有当得到信号量的进程或者线程才能够进入临界区,执号量只有当得到信号量的进程或者线程才能够进入临界区,执行临界代码。信号量与自旋锁的最大不同点在于,

11、当一个进程行临界代码。信号量与自旋锁的最大不同点在于,当一个进程试图去获取一个已经锁定的信号量时,试图去获取一个已经锁定的信号量时,进程不会像自旋锁一样进程不会像自旋锁一样在远处忙等待,在信号量中采用了另一种方式,这中方式如下在远处忙等待,在信号量中采用了另一种方式,这中方式如下所述。所述。7.4.2 7.4.2 信号量的实现信号量的实现根据不同的平台,其提供的指令代码有所不同,所以根据不同的平台,其提供的指令代码有所不同,所以信号量的实现也有所不同。信号量的实现也有所不同。下面详细介绍一下这个结构体的各个成员变量:下面详细介绍一下这个结构体的各个成员变量:1lock自旋锁自旋锁2count变

12、量变量3等待队列等待队列7.4.3 7.4.3 信号量的使用信号量的使用在在Linux中,信号量的类型为中,信号量的类型为struct semaphore。内核提。内核提供了一系列的函数来对供了一系列的函数来对struct semaphore进行操作。下面将进行操作。下面将对信号量的操作方法进行简要的介绍。对信号量的操作方法进行简要的介绍。1定义和初始化自旋锁定义和初始化自旋锁2锁定信号量锁定信号量3释放信号量释放信号量4使用信号量使用信号量5信号量用于同步操作信号量用于同步操作7.4.4 7.4.4 自旋锁与信号量的对比自旋锁与信号量的对比自旋锁和信号量是解决并发控制的两个很重要的方法。在自

13、旋锁和信号量是解决并发控制的两个很重要的方法。在使用时,应该如何选择它们其中的一种方法呢?这要根据被包使用时,应该如何选择它们其中的一种方法呢?这要根据被包含资源的特定来确定。含资源的特定来确定。自旋锁是一种最简单的保护机制,从上面的代码分析中,自旋锁是一种最简单的保护机制,从上面的代码分析中,可以看出自旋锁的定义只有一个结构体成员。当被包含的代码可以看出自旋锁的定义只有一个结构体成员。当被包含的代码能够在很短的时间内执行完成时,那么使用自旋锁是一种很好能够在很短的时间内执行完成时,那么使用自旋锁是一种很好的选择。因为自旋锁只是忙等待,不会进入睡眠。要知道,睡的选择。因为自旋锁只是忙等待,不会

14、进入睡眠。要知道,睡眠是一种非常浪费时间的操作。眠是一种非常浪费时间的操作。7.5 7.5 完成量完成量在驱动程序开发中,一种常见的情况是:一个线程需在驱动程序开发中,一种常见的情况是:一个线程需要等待另一个线程执行完某个操作后,才能够继续执行。上要等待另一个线程执行完某个操作后,才能够继续执行。上面讲的信号量其实也能够完成这种工作,不过其效率不如面讲的信号量其实也能够完成这种工作,不过其效率不如Linux中专门针对这种情况的完成量机制。本节将对完成量中专门针对这种情况的完成量机制。本节将对完成量进行详细的介绍。进行详细的介绍。7.5.1 7.5.1 完成量概述完成量概述Linux中提供了一种

15、机制来实现一个线程发送一个信号来通知中提供了一种机制来实现一个线程发送一个信号来通知另一个线程开始完成某个任务,这种机制就是完成量。完成量的目另一个线程开始完成某个任务,这种机制就是完成量。完成量的目的是告诉一个线程某个事件已经发生,可以在此事件基础上做你想的是告诉一个线程某个事件已经发生,可以在此事件基础上做你想做的另一个事件了。其实完成量和信号量比较类似,但是在这种线做的另一个事件了。其实完成量和信号量比较类似,但是在这种线程通信的情况下,使用完成量有更高的效率。在内核中,程通信的情况下,使用完成量有更高的效率。在内核中,可以进程可以进程看见使用完成量的代码。完成量是一种轻量级的机制,这种

16、机制在看见使用完成量的代码。完成量是一种轻量级的机制,这种机制在一个线程希望告诉另一个线程某个工作已经完成的情况下是非常有一个线程希望告诉另一个线程某个工作已经完成的情况下是非常有用的。用的。7.5.2 7.5.2 完成量的实现完成量的实现完成量是实现两个任务之间同步的简单方法,在内核完成量是实现两个任务之间同步的简单方法,在内核中完成量由中完成量由struct completion结构体来表示。该结构体定义结构体来表示。该结构体定义在在includelinuxcompletion.h文件中。文件中。下面详细介绍一下这个结构体的两个成员变量:下面详细介绍一下这个结构体的两个成员变量:1done成员成员2wait成员成员7.5.3 7.5.3 完成量的使用完成量的使用在在Linux中,信号量的类型为中,信号量的类型为struct completion。内核。内核提供了一系列的函数来对提供了一系列的函数来对struct completion进行操作。下面进行操作。下面将对完成量的操作方法进行简要的介绍:将对完成量的操作方法进行简要的介绍:1定义和初始化完成量定义和初始化完成量2等待完成量等待完成量3释放完成量释放完成量4使用完成量使用完成量7.6 7.6 小结小结本章介绍了本章介绍了Li

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论