读锁在C++中有什么作用?
使用 a 时shared_mutex,有独占访问和共享访问。独占访问只允许一个线程访问资源,而其他线程被阻塞,直到持有锁的线程释放锁。共享访问是指允许多个线程访问资源但处于“读锁”之下。什么是“读锁”?我不明白读锁的含义。有人可以给出“读锁”的代码示例。
我对读锁的猜测:我认为读锁只允许线程运行代码而不修改任何内容。显然,当我尝试一些代码时我错了,但它并没有像我想象的那样工作。
再一次,有人可以帮助我理解什么是读锁。
谢谢。
回答
你的猜测非常接近正确,但有一点微妙。
读/写区别显示了储物柜的意图,它不限制储物柜实际做什么。如果读锁决定修改受保护的资源,它可以,并且会随之而来。但是,这与线程在没有锁定的情况下修改受保护资源没有什么不同。程序员必须遵守规则,否则就要付出代价。
至于区别,读锁是针对只想读取共享资源的情况。十亿个不同的线程可以安全地执行此操作,因为在执行此操作时资源不会发生变化。
写入锁定,在另一方面,意味着你要更改的共享资源,所以应该没有读者(或其他作家)与活动的锁。
这是一种基于使用情况优化锁的方法。例如,考虑以下锁定队列,最早的条目在右侧,并且不允许队列跳转(如果写入器当前被阻塞,则读取器在写入器之前跳转):
(queue here) -> RR W RRRR -> (action here)
- “资源控制器”可以允许队列头的所有四个
R储物柜同时访问。 - 然后,
W储物柜必须等到所有这些锁都被释放才能获得访问权限。 - 最后两个
R储物柜必须等到W储物柜释放后才能同时访问。
换句话说,任何给定时间可能的锁持有者是(互斥的):
- 任意数量的读者。
- 一位作家。
顺便说一句,您还可以使用其他可能的优化策略。
例如(如前所述),如果看起来作者无论如何都必须等待一段时间(例如当前有大量读者),您可能希望读者能够跳队列。
这充满了危险,因为您可能会使写储物柜饿死,但只要队列跳线的数量有限制,就可以做到这一点。
我过去做过。从内存(很久以前为 6809 CPU 内置 BCPL 的嵌入式操作系统的内存,它显示了我的年龄比我可能想要的更多),作者在其锁定请求中包含了它满意的最大队列跳线数(默认为零),未来读者的排队也考虑到了这一点。