为什么要有锁机制?
共享资源被并发使用的时候,当有可能破坏资源的一致性的时候,就需要一种同步机制,保证资源可以被使用正确。
通俗地理解锁机制
厕所浴室:一种共享资源
爸爸、妈妈、小孩:用户
当有一个人进入厕所后,该资源已经被占用,就会将门锁住。另一个人只能排队等待,直到资源被释放(开门离开),下一个人才能使用。
锁机制概览
名称 | 定义 | 特点 | 应用场景 | 备注 |
---|---|---|---|---|
原子操作(atomic) | 所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。 | 需要硬件的支持。都使用汇编语言实现 | 原子操作主要用于实现资源计数,很多引用计数(refcnt)就是通过原子操作实现的 | |
互斥锁(mutex) | 每个对象都对应于一个可称为” 互斥锁” 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。 | 同一时间只能有一个任务持有互斥锁,而且只有这个任务可以对互斥锁进行解锁。互斥锁不能用于中断上下文。互斥锁比当前的内核信号量选项更快,并且更加紧凑。会引起调用者睡眠。 | ||
自旋锁(Spanlock) | 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠。 | 如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,”自旋”一词就是因此而得名。由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁 | 调用资源的时间短。可以在任何上下文使用 | |
顺序锁(seqlock) | 用于能够区分读与写的场合,并且是读操作很多、写操作很少,写操作的优先权大于读操作。 | |||
RCU(read-copy-update) | RCU也是用于能够区分读与写的场合,并且也是读多写少,但是读操作的优先权大于写操作(与seqlock相反) | |||
信号量 | Linux内核的信号量在概念和原理上与用户态的SystemV的IPC机制信号量是一样的,但是它绝不可能在内核之外使用,因此它与SystemV的IPC机制信号量毫不相干 | 信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用(_trylock的变种能够在中断上下文使用) | 信号量可以类比为一把锁(共享资源)对应多把钥匙(信号量),只有持有钥匙的人才能开锁 |