- 1、本文档共20页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
信号量和自旋锁.ppt
linux内核同步 进程A和进程B同时对(不同进程) xxx_count (共享资源) 进行操作,产生了竞争行为! 想一想你(A)正上厕所的时候 一个美女(B)闯进来的情形吧 解决方法:保证对共享资源的互斥访问 如何做到互斥访问? 访问共享资源的代码区块叫做“临界区”, 临界区需要以某种互斥机制加以保护:自旋锁,信 号量等 信号量 Linux中的信号量是一种睡眠锁。假如进程A先持有信号量F ,然后进程B试图获得已经被进程A持有的信号量F时(假设 信号量F资源值为1),信号量会将进程B推入等待队列,然 后让其睡眠。当持有信号量的进程A将信号量F释放后,进程 B才会被被唤醒,从而获得这个信号量,继续执行进程B的代 码。 信号量的睡眠特性,使得信号量适用于锁会被长时间持有的 情况;信号量只能在进程中使用,不能在中断中使用; 信号量基本使用形式为: 定义信号量 struct semaphore sem; 初始化信号量 void sema_init(struct semaphore * sem, int val); 初始化互斥信号量 void init_MUTEX(struct semaphore *sem); 等同于:sema_init(struct semaphore *sem, 1); 获得信号量 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值,它不会导致调用者睡眠,可以在中断上下文使用 释放信号量 void up(struct semaphore *sem) 该函数释放信号量sem,唤醒等待者 并发和竟态 信号量使用注意: 1.可以长期加锁 2.只能用于进程上下文,不能用于中断上下文 3.在持有自旋锁的同时,不能持有信号量 linux内核中可能引起互斥访问的情形: 1.进程和进程之间(如上述讨论) 解决方式:信号量 2.进程和其它内核代码 解决方式:自旋锁 3.进程和中断代码 解决方式:自旋锁 自旋锁 自旋锁最多只能被一个内核任务持有。要是锁未被持有,请 求他的内核任务便立即得到它并且继续进行。如果一个内核 任务试图请求一个已经被别的内核任务持有的自旋锁,那么 CPU就会一直进行忙循环——旋转——等待锁重新可用。自 旋锁的使用方法如下: spin_lock(mr_lock);//加锁 //临界区代码 spin_unlock(mr_lock);//解锁 自旋锁 初始化自旋锁: spinlock_t my_lock = SPIN_LOCK_UNLOCKED; 或者在运行时使用: void spin_lock_init(spinlock_t *lock); 得到自旋锁: void spin_lock(spinlock_t *lock); 释放自旋锁 void spin_unlock(spinlock_t *lock); 自旋锁 相应的释放函数 void spin_unlock(spinlock_t *lock); void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags); void spin_unlock_irq(spinlock_t *lock); void spin_unlock_bh(spinlock_t *lock); 自旋锁使用案例 drivers/net/8139cp.c cp_close()--进程上下文 spin_lock_irqsave(cp-lock, flags); netif_stop_queue(dev); netif_carrier_off(dev); cp_stop_hw(cp); spin_unlock_irqrestore(cp-lock, flags); 自旋锁 自旋锁使用注意: 1.不可以长期加锁,短期加锁 2.会有系统开销(cpu忙转),不可滥用 3.在持有自旋锁的同时,不能
文档评论(0)