排他锁和共享锁有什么区别?


118

根据维基百科,

共享锁有时称为“读锁”,排他锁有时称为“写锁”。

您能否解释“共享”和“排他”一词背后的原因?


非排他锁是共享锁的另一个名称吗?
Ramesh Papaganti

Answers:


417

我写下这个答案是因为我认为这将是一个有趣的(而且很合适)的比喻:

在教室中,将一个可锁定的对象想像成一块黑板(可锁定),其中包含一名教师(作家)和许多学生(读者)。

当老师在黑板上写东西(排他锁)时:

  1. 没有人可以读取它,因为它仍在被写入,并且她阻止了您的视图=> 如果一个对象被排他地锁定,则无法获得共享锁

  2. 其他老师也不会上书,也不会开始写作,否则黑板会变得不可读,并使学生感到困惑=> 如果某个对象被排他锁,则无法获得其他排他锁

当学生正在阅读(共享锁)时,黑板上的内容是:

  1. 他们都可以读取其中的内容,一起=> 多个共享锁可以共存

  2. 老师等待他们完成阅读,然后再清空黑板以写更多=> 如果已经存在一个或多个共享锁,则无法获得排他锁


2
很好的解释。但是,邮政局要求关于“共同”和“独占”面额的起源,而不是对热值本身的解释。
serhio 2014年

是“如果已经存在一个或多个共享锁,则无法获取排他锁”。是真的?ReentrantReadWriteLock的术语?我以为可以随时获取写锁定,否则由于连续读取而可能发生写饥饿。
卡纳加韦卢·苏古玛'16

1
@KanagaveluSugumar,是的,这是真的。当另一个实体已经在同一对象上拥有读锁时,您根本无法获得写锁。这就是读写锁的全部要点。如果您正巧在别人正在阅读时覆盖某些内容,那么他​​们会读些什么?我不知道您为什么选择选择特定的“可重入”读写锁,但是可重入意味着可重入锁的所有者可以再次对其进行“锁定()”,lock()之后的所有后续调用第一个将立即成功返回。也就是说,您可以成功锁定您已经拥有的东西。
ArjunShankar '16

2
您还提到“我认为可以随时获取写入锁定,否则由于连续读取而可能导致写入不足”。当某些其他实体已经拥有读/写锁时,无法获得写锁。什么可以发生的是,如果多个实体已经等待锁定的对象,然后等待writer被优先于等待读者当锁选谁得到锁定下一个(当它是由它的当前所有者解锁)。这是关于政策的
ArjunShankar '16

谢谢!我选择了ReentrantReadWriteLock; 因为那是Java中ReadWriteLock的实现类。然后,是否有任何标志升高或设置了更高的优先级,以说写线程开始等待时还要等待其他新的读线程?因为如何避免由于连续读取请求而导致写线程不足?
卡纳加韦卢·苏古玛'16

33

这很简单。读锁也称为共享锁,因为一个以上的进程可以同时读取。读锁定的目的是防止其他进程获取写锁定。相比之下,写锁在写操作完成时禁止所有其他操作,这就是为什么将其描述为互斥的。

因此,读锁显示“您现在可以阅读,但是如果要写,则必须等待”,而写锁则显示“您必须等待”。


我知道您正在研究中以支持您的学习,但是我无法抵制演讲的冲动。

不恰当地使用锁定是导致性能头痛的主要原因。使用区分读和写锁的锁系统是一个好的开始,但是精心设计有时可以消除很多锁的需求。例如,会话状态永远不应保存在每个状态元素的一个全局集合中。

我实际上已经看到了。这是一个残酷的设计,导致对会话状态的每一次最后更改都造成装箱和对集合的更改,从而导致持久的写锁定。开销大打折扣,有效地将服务器缩减为单线程行为。

简单地将所有会话状态汇总到一个结构中是一个巨大的进步。对会话状态的更改仅更改了会话状态结构的成员的值。由于没有其他会话机会甚至没有机会直接引用会话的状态,因此唯一要更新的集合是会话列表。结果,在此期间完全不需要锁定会话,仅在开始和结束时,吞吐量就提高了3000倍。

另一种常见的锁定方案是在用户应用程序的线程之间共享资源。大多数现代框架使用消息而不是锁来解决此问题。当您“过渡到UI线程”时,您实际上是在排队一条消息,其中包含函数指针和一些参数(或委托和堆栈框架,具体取决于实现)。


6
  • 互斥锁或写锁为进程提供了对文件的指定部分进行写操作的互斥访问权限。设置写锁定后,没有其他进程可以锁定文件的该部分。

  • 共享或读取锁定禁止任何其他进程在文件的指定部分上请求写入锁定。但是,其他进程可以请求读取锁。

有关更多信息:http : //www.gnu.org/software/libc/manual/html_node/File-Locks.html


2

数据库方面的原理也是如此。根据Oracle文档

排他锁定模式可防止关联资源被共享。获得此锁定模式以修改数据。第一个排他地锁定资源的事务是唯一可以更改资源的事务,直到释放排他锁为止。

共享锁定模式允许根据相关操作共享关联的资源。读取数据的多个用户可以共享数据,并持有共享锁,以防止编写者(需要排他锁)并发访问。多个事务可以
获取同一资源上的共享锁。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.