常见锁
介绍一下几种经典的锁
操作系统中的锁是用来控制多线程对共享资源的访问权限的限制。
不同类型的锁用于处理不同的场景和需求,使用合适的锁能保证程序的正确性和提高系统性能。
互斥锁,自旋锁,读写锁,悲观锁,乐观锁
互斥锁和自旋锁
两种最底层的锁
互斥锁:独占锁。控制某一进程独占共享资源。互斥锁加锁失败后,会释放CPU给其他进程。
自旋锁:循环等待获取锁。加锁失败后,线程进入忙等待,直到拿到自旋锁。
互斥锁加锁失败后,操作系统内核会将该线程置于睡眠状态,直到该锁被释放,内核会在合适时机唤醒该线程。因此互斥锁加锁失败会有两次线程上下文切换的成本。内核会将线程状态从运行到睡眠,然后把CPU切换给其他线程。锁被释放后,将线程从睡眠变为就绪,等待合适时机将CPU切换给线程
读写锁
读写锁允许多读,写操作独占。读写锁适用于能明确区分读操作和写操作的场景。写锁是独占锁,任何时刻只有一个线程持有写锁,读锁是共享锁,读锁可以被多个线程同时持有。
读写锁可以分类为读优先锁和写优先锁和公平读写锁。
读优先锁和写优先锁都有可能会将对方线程饿死。公平读写锁是用队列把获取锁的线程排队,不管是写线程还是读线程都按照先进新出的原则加锁。
乐观锁和悲观锁
互斥锁,自旋锁,读写锁都属于悲观锁。悲观锁认为多线程同时修改共享资源的概率比较高,所以线程访问共享资源时都会加锁。
乐观锁是直接让进程先修改了共享资源,如果发现同时修改的情况才会放弃本次操作。乐观锁全程没有加锁,也叫无锁编程。乐观锁一旦发生冲突重试成本非常高,因此只有在冲突概率低,加锁成本高的场景下才使用乐观锁
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Priska's blog!