当前位置: 首页 > 图文教程 > 操作系统 > Unix/Linux > 深入浅出Linux设备驱动之并发控制

Unix/Linux
查看linux 下已经安装的软件包信息
linux 系统中软件raid 配置方法
linux 下MySQL服务器的启动与停止
linux 系统下FTP服务器配置方法
Linux系统下如何挂载U盘,硬盘,光驱
linux 系统下DHCP服务器 配置方法
Linux系统下软件的安装与卸载
在Fedora 9中启用ext4文件系统的方法
linux下挂载(mount)光盘镜像文件、移动硬盘、U盘、Windows网络共享和NFS网络共享
Linux查看文件夹大小的命令
LINUX系统grub常见错误分析
llinux fdisk分区工具 使用方法
linux 系统telnet乱码
rhythmbox 乱码的解决方法
linux单网卡绑定多ip
tar.gz 和tar.bz2 详细解释
linux学习笔记
linux系统rpm安装包详解
linux 服务器常用维护命令
出现The file /boot/grub/stage1 not read cor 解决办法

Unix/Linux 中的 深入浅出Linux设备驱动之并发控制


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-01   浏览: 193 ::
收藏到网摘: n/a

  在驱动程序中,当多个线程同时访问相同的资源时(驱动程序中的全局变量是一种典型的共享资源),可能会引发"竞态",因此我们必须对共享资源进行并发控制。Linux内核中解决并发控制的最常用方法是自旋锁与信号量(绝大多数时候作为互斥锁使用)。

  自旋锁与信号量"类似而不类",类似说的是它们功能上的相似性,"不类"指代它们在本质和实现机理上完全不一样,不属于一类。

  自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环查看是否该自旋锁的保持者已经释放了锁,"自旋"就是"在原地打转"。而信号量则引起调用者睡眠,它把进程从运行队列上拖出去,除非获得锁。这就是它们的"不类"。

  但是,无论是信号量,还是自旋锁,在任何时刻,最多只能有一个保持者,即在任何时刻最多只能有一个执行单元获得锁。这就是它们的"类似"。

  鉴于自旋锁与信号量的上述特点,一般而言,自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用;信号量适合于保持时间较长的情况,会只能在进程上下文使用。如果被保护的共享资源只在进程上下文访问,则可以以信号量来保护该共享资源,如果对共享资源的访问时间非常短,自旋锁也是好的选择。但是,如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。

  与信号量相关的API主要有:

  定义信号量

struct semaphore sem;


  初始化信号量

void sema_init (struct semaphore *sem, int val);


  该函数初始化信号量,并设置信号量sem的值为val

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);

  获得信号量

void down(struct semaphore * sem);


  该函数用于获得信号量sem,它会导致睡眠,因此不能在中断上下文使用;

int down_interruptible(struct semaphore * sem);


  该函数功能与down类似,不同之处为,down不能被信号打断,但down_interruptible能被信号打断;

int down_trylock(struct semaphore * sem);


  该函数尝试获得信号量sem,如果能够立刻获得,它就获得该信号量并返回0,否则,返回非0值。它不会导致调用者睡眠,可以在中断上下文使用。

  释放信号量

void up(struct semaphore * sem);


  该函数释放信号量sem,唤醒等待者。

  与自旋锁相关的API主要有:

  定义自旋锁

spinlock_t spin;


  初始化自旋锁

spin_lock_init(lock)


  该宏用于动态初始化自旋锁lock

  获得自旋锁