Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1213302
  • 博文数量: 261
  • 博客积分: 4196
  • 博客等级: 上校
  • 技术积分: 3410
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-17 17:05
文章分类

全部博文(261)

文章存档

2018年(1)

2017年(22)

2016年(2)

2015年(8)

2014年(27)

2013年(40)

2012年(161)

分类: LINUX

2013-04-17 13:46:04

Linux的信号量是一种睡眠锁,这个不同于自旋锁.如果有一个任务试图获得一个已经被占用的信号量时,信号量会将其推进一个等待队列(具体可以参考进程 的活动状态),然后让其睡眠,此时处理器能重获自由,而去执行其他代码.当持有信号量的进程将信号量释放后,处于等待队列中的那个进程会被唤醒,并获得该 信号量.
所以和自旋锁的区别是:
1)信号量适用于锁会被长时间持有的情况
2)持有信号量锁的线程可以睡眠,而持有自旋锁的线程是不允许睡眠的
3)信号锁不会禁止内核抢占
4)最重要的信号锁同时允许任意数量的锁持有者,而自旋锁在同一时刻最多只允许一个任务持有他
因为不受睡眠的限制,所以信号量锁用起来要方便一些.

信号量锁的持有者数目可以在声明信号量时指定.当信号量的持有者被声明为只允许一个持有者时,此时的信号量又被称为互斥信号量.
在适用信号量的时候基本上用到的都是互斥信号量.

信号量的接口:
信号量的实现是与体系结构相关,具体实现定义在文件中.
struct semaphore类型用来表示信号量:
static DECLARE_SEMAPHORE_GENERIC(name,count);//name为信号量的名字,count为持有者数目.
创建更为普通的互斥信号量:
static DECLARE_MUTEX(name);

当动态创建信号量时,可是使用:(sem是指针变量)
DECLARE_MUTEX(sem);  //该宏声明一个信号量sem 并初始化其值为0

DECLARE_MUTEX_LOCKED(sem);  //该宏声明一个互斥锁sem,初始值设为0,即在创建时就处在已锁状态。因此对于这种锁,一般是先释放后获得

sema_init(sem,val);//初始化设置信号量,并且设置其初始值为val

init_MUTEX(sem);  //初始化一个互斥锁,将其值设定为1

init_MUTEX_LOCKED(sem);  //此函数初始化一个互斥锁sem,初始值设为0,即在创建时就处在已锁状态。

使用down(sem); 尝试获取信号量sem,他会导致睡眠, 因此不能在中断上下文中使用。该函数将sem减1,如果sem非负,就直接挂起,直到其他任务释放该信号量才继续运行。

使用down_interruptible(sem)试图获得指定的信号量,如果失败,进程会以TASK_INTERRUPTIBLE状态进入睡眠.此函数与down类似,但是down不会被信号(signal)打断,但是此函数能被打断。如返回0表示信号量正常返回,如果被信号打断,返回-EINTR

使用down_trylock(sem),可以尝试以非堵塞的方式来获得指定的信号量,在信号量已被占用时,立刻返回非0值;否则返回0,并立刻让你成功持有信号量锁。它不会导致使用者睡眠,所以可以在中断上下文中使用

使用up(sem),则是可以释放指定的信号量.

与自旋锁一样,信号量也有读写信号量,读写信号在内核中是由rw_semaphore结构表示,定义在文件中
阅读(1047) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~