欢迎来到天天文库
浏览记录
ID:19279697
大小:74.00 KB
页数:10页
时间:2018-09-30
《内核同步机制-信号量 互斥锁 读-写信号量 sema mutex rwsem》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、内核同步机制-信号量/互斥锁/读-写信号量sema,mutex,rwsem目录1信号量o1.1通用信号量o1.2互斥锁o1.3读/写信号量信号量通用信号量用户类进程之间使用信号量(semaphore)进行同步,内核线程之间也使用了信号量。信号量与自旋锁类似,保护临界区代码。但信号量与自旋锁有一定的区别,信号量在无法得到资源时,内核线程处于睡眠阻塞状态,而自旋锁处于忙等待状态。因此,如果资源被占用时间很短时,使用自旋锁较好,因为它可节约调度时间。如果资源被占用的时间较长,使用信号量较好,因为可让CPU调度去做其它进程的工作。操作信号量的API函数说
2、明如表6。表6信号量API函数功能说明函数定义功能说明sema_init(structsemaphore*sem,intval)初始化信号量,将信号量计数器值设置val。down(structsemaphore*sem)获取信号量,不建议使用此函数。down_interruptible(structsemaphore*sem)可被中断地获取信号量,如果睡眠被信号中断,返回错误-EINTR。down_killable(structsemaphore*sem)可被杀死地获取信号量。如果睡眠被致命信号中断,返回错误-EINTR。down_trylock
3、(structsemaphore*sem)尝试原子地获取信号量,如果成功获取,返回0,不能获取,返回1。down_timeout(structsemaphore*sem,longjiffies)在指定的时间jiffies内获取信号量,若超时未获取,返回错误-ETIME。up(structsemaphore*sem)释放信号量sem。样例:信号量的使用下面函数do_utimes利用信号量防止多个线程对文件系统节点inode同时进行访问。其列出如下(在fs/open.c中):longdo_utimes(char__user*filename,stru
4、cttimeval*times){ structinode*inode; …… down(&inode->i_sem);//获取信号量 error=notify_change(nd.dentry,&newattrs);//修改inode中值 up(&inode->i_sem);//释放信号量 ……} 下面说明信号量API函数。(1)信号量结构semaphore信号量用结构semaphore描述,它在自旋锁的基础上改进而成,它包括一个自旋锁、信号量计数器和一个等待队列。用户程序只能调用信号量API函数,而不能直接访问信号量结
5、构,其列出如下(在include/linux/semaphore.h中):structsemaphore{ spinlock_tlock; unsignedintcount; structlist_headwait_list;};(2)初始化函数sema_init函数sema_init初始化信号量,将信号量值初始化为n,其列出如下:staticinlinevoidsema_init(structsemaphore*sem,intval){ staticstructlock_class_key__key; *sem=(struc
6、tsemaphore)__SEMAPHORE_INITIALIZER(*sem,val); /*初始化一个锁的实例,用于调试中获取信号量的调试信息*/ lockdep_init_map(&sem->lock.dep_map,"semaphore->lock",&__key,0);}#define__SEMAPHORE_INITIALIZER(name,n)/{/ .lock=__SPIN_LOCK_UNLOCKED((name).lock),///初始化自旋锁 .count=n,///将信号量计数器赋值为n .wait_lis
7、t=LIST_HEAD_INIT((name).wait_list),///初始化等待队列}(3)可中断获取信号量函数down_interruptible函数down_interruptible获取信号量,存放在参数sem中。它尝试获取信号量,如果其他线程被允许尝试获取此信号量,则将本线程睡眠等待。如果有一个信号中断睡眠,则它返回错误-EINTR。如果成功获取信号量,函数返回0。函数down_interruptible列出如下(在kernel/semaphore.c中):intdown_interruptible(structsemaphore*
8、sem){ unsignedlongflags; intresult=0; spin_lock_irqsave(&sem->
此文档下载收益归作者所有