Answers:
我写下这个答案是因为我认为这将是一个有趣的(而且很合适)的比喻:
在教室中,将一个可锁定的对象想像成一块黑板(可锁定),其中包含一名教师(作家)和许多学生(读者)。
当老师在黑板上写东西(排他锁)时:
没有人可以读取它,因为它仍在被写入,并且她阻止了您的视图=> 如果一个对象被排他地锁定,则无法获得共享锁。
其他老师也不会上书,也不会开始写作,否则黑板会变得不可读,并使学生感到困惑=> 如果某个对象被排他锁,则无法获得其他排他锁。
当学生正在阅读(共享锁)时,黑板上的内容是:
他们都可以读取其中的内容,一起=> 多个共享锁可以共存。
老师等待他们完成阅读,然后再清空黑板以写更多=> 如果已经存在一个或多个共享锁,则无法获得排他锁。
lock()
之后的所有后续调用第一个将立即成功返回。也就是说,您可以成功锁定您已经拥有的东西。
writer
被优先于等待读者当锁选谁得到锁定下一个(当它是由它的当前所有者解锁)。这是关于政策的。
这很简单。读锁也称为共享锁,因为一个以上的进程可以同时读取。读锁定的目的是防止其他进程获取写锁定。相比之下,写锁在写操作完成时禁止所有其他操作,这就是为什么将其描述为互斥的。
因此,读锁显示“您现在可以阅读,但是如果要写,则必须等待”,而写锁则显示“您必须等待”。
我知道您正在研究中以支持您的学习,但是我无法抵制演讲的冲动。
不恰当地使用锁定是导致性能头痛的主要原因。使用区分读和写锁的锁系统是一个好的开始,但是精心设计有时可以消除很多锁的需求。例如,会话状态永远不应保存在每个状态元素的一个全局集合中。
我实际上已经看到了。这是一个残酷的设计,导致对会话状态的每一次最后更改都造成装箱和对集合的更改,从而导致持久的写锁定。开销大打折扣,有效地将服务器缩减为单线程行为。
简单地将所有会话状态汇总到一个结构中是一个巨大的进步。对会话状态的更改仅更改了会话状态结构的成员的值。由于没有其他会话机会甚至没有机会直接引用会话的状态,因此唯一要更新的集合是会话列表。结果,在此期间完全不需要锁定会话,仅在开始和结束时,吞吐量就提高了3000倍。
另一种常见的锁定方案是在用户应用程序的线程之间共享资源。大多数现代框架使用消息而不是锁来解决此问题。当您“过渡到UI线程”时,您实际上是在排队一条消息,其中包含函数指针和一些参数(或委托和堆栈框架,具体取决于实现)。
互斥锁或写锁为进程提供了对文件的指定部分进行写操作的互斥访问权限。设置写锁定后,没有其他进程可以锁定文件的该部分。
共享或读取锁定禁止任何其他进程在文件的指定部分上请求写入锁定。但是,其他进程可以请求读取锁。
有关更多信息:http : //www.gnu.org/software/libc/manual/html_node/File-Locks.html