首页 > 代码库 > 锁开销

锁开销

一、互斥锁的开销主要在内核态与用户态的切换:

  申请锁时,从用户态进入内核态,申请到后从内核态返回用户态(两次切换);没有申请到时阻塞睡眠在内核态。使用完资源后释放锁,从用户态进入内核态,唤醒阻塞等待锁的进程,返回用户态(又两次切换);被唤醒进程在内核态申请到锁,返回用户态(可能其他申请锁的进程又要阻塞)。所以,使用一次锁,包括申请,持有到释放,当前进程要进行四次用户态与内核态的切换。同时,其他竞争锁的进程在这个过程中也要进行一次切换。

  进程上下文切换的直接消耗包括CPU寄存器保存和加载,需要调度时有内核调度代码的执行。

 

二、自旋锁:

  与互斥锁不同的是自旋锁不会引起调用者睡眠。如果自旋锁已经被别的进程保持,调用者就轮询(不断的消耗CPU的时间)是否该自旋锁的保持者已经释放了锁("自旋"一词就是因此而得名)。

三、互斥锁、自旋锁的使用场景:

1.由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠,自旋锁的效率远高于互斥锁。

2.自旋锁保持期间是抢占失效的。如果被保护的共享资源需要在中断上下文访问(包括中断上半部和下半部[1]),就必须使用自旋锁。

 

 在ISR中都不能进行进程切换。因为ISR不属于任何进程,而切换只能发生在进程上下文中。虽然ISR在执行过程中要

使用进程的系统堆栈,但那只是借用,堆栈并不属于isr,而是属于进程。  http://www.chinaunix.net/old_jh/4/902033.html

 

通常32位Linux内核,进程地址空间划分0~3G为用户空间,3~4G为内核空间。内核空间中的内核代码、数据,为所有进程共享,由MMU映射在相同的物理内存地址。

 

 

技术分享

  进程进入内核态后,内核代码所使用的栈并不是用户空间中的栈,而是内核空间的栈,进程的“内核栈”。

 

[1]?怎么理解“中断运行在中断上下文,没有一个所谓的中断描述符来描述它,它不是操作系统调度的单位。一旦在中断上下文中睡眠,首先无法切换上下文(因为没有中断描述符,当前上下文的状态得不到保存),其次,没有人来唤醒它,因为它不是操作系统的调度单位。 ”

 

锁开销