3

我想知道并且需要可用于减少低级锁定的策略。然而,这里的问题是这不是服务器应用程序的新代码(具有数万行 C++ 代码),所以我不能只重写整个事情。

我担心现在可能无法解决这个问题(为时已晚)。但是,我想听听其他人使用过的好模式。

现在有太多的锁,没有那么多的冲突,所以这是一个偏执引起的硬件性能问题。描述代码的最佳方式是单线程代码突然充满了锁。

4

3 回答 3

4

为什么需要消除低级锁定?你有死锁问题吗?你有性能问题吗?还是缩放问题?锁通常是争用的还是非争用的?

你用的是什么环境?例如,C++ 中的答案与 Java 中的答案不同。例如,Java 6 中的非竞争同步块实际上在性能方面相对便宜,因此只需升级您的 JRE 可能会让您解决任何您试图解决的问题。通过切换到不同的编译器或锁定库,C++ 中可能会有类似的性能提升。

一般来说,有几种策略可以让您减少获得的互斥锁数量。

首先,任何只能从单个线程访问的东西都不需要互斥体。

其次,任何不可变的东西都是安全的,只要它是“安全发布的”(即以这样一种方式创建,即部分构造的对象对另一个线程永远不可见)。

第三,现在大多数平台都支持原子写入——当需要保护一个原始类型(包括指针)时,这会有所帮助。这些工作与数据库中的乐观锁定非常相似。您还可以使用原子写入来创建无锁算法来替换更复杂的类型,包括 Map 实现。然而,除非你非常非常优秀,否则最好借用别人的调试实现(java.util.concurrent 包包含很多很好的例子)——众所周知,在编写自己的算法时很容易意外引入错误。

第四,扩大互斥锁的范围会有所帮助——要么简单地保持打开互斥锁的时间更长,而不是不断地锁定和解锁它,要么锁定一个“更大”的项目——对象而不是它的一个属性,例如. 但是,这必须非常小心;您可以通过这种方式轻松引入问题。

于 2008-09-24T12:33:49.413 回答
1

程序的线程模型必须在编写一行之前确定。任何模块,如果与程序的其余部分不一致,都可能导致应用程序崩溃、死锁损坏。

如果您有机会重新开始,请尝试确定程序中可以并行完成的大型功能,并使用线程池来安排任务。提高效率的诀窍是尽可能避免互斥体,并(重新)对您的应用程序进行编码,以避免高级别资源争用。

于 2008-09-24T07:06:04.100 回答
0

当您寻找在没有显式锁的情况下以原子方式更新共享状态的方法时,您可能会在此处此处找到一些答案。

于 2008-09-24T15:31:23.747 回答