134

根据维基百科,

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

你能解释一下“共享”和“独占”这两个词背后的原因吗?

4

4 回答 4

496

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

将可锁定对象想象为教室中的黑板(可锁定),其中包含教师(作家)和许多学生(读者)。

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

  1. 没有人可以阅读它,因为它仍在编写中,而且她挡住了你的视线 =>如果一个对象被独占锁定,则无法获得共享锁

  2. 其他老师也不会上来开始写,或者板子变得不可读,迷惑学生=>如果一个对象被排他锁,其他排他锁就无法获得

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

  1. 他们都可以一起阅读上面的内容 =>多个共享锁可以共存

  2. 老师等他们读完才清板写更多 =>如果已经存在一个或多个共享锁,则无法获取排他锁

于 2012-08-07T00:19:25.120 回答
41

这很简单。读锁也称为共享锁,因为多个进程可以同时读取。读锁的目的是防止另一个进程获取写锁。相比之下,写锁在写操作完成时禁止所有其他操作,这就是它被描述为独占的原因。

所以读锁说“你现在可以读,但如果你想写,你必须等待”,而写锁说“你必须等待”。


我知道您正在研究以支持您的学习,但我无法抗拒演讲的冲动。

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

我实际上已经看到这样做了。这是一个残暴的设计,每次会话状态的最后一次更改都会导致装箱和对集合的更改,从而导致长时间的写锁定。开销非常严重,有效地将服务器减少到单线程行为。

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

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

于 2012-08-06T23:59:44.770 回答
9
  • 独占锁或写锁为进程提供了对文件指定部分的独占访问权限。当写锁到位时,没有其他进程可以锁定文件的该部分。

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

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

于 2012-08-07T00:00:30.230 回答
2

数据库端的原理也是一样的。根据 Oracle 文档

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

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

于 2013-08-22T04:05:53.117 回答