摆脱低级别锁定的技巧

时间:2008-09-24 06:52:04

标签: language-agnostic design-patterns locking

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

我担心现在可能没有解决这个问题的方法(为时已晚)。但是我想听听别人用过的好模式。

现在有太多锁定而没有多少冲突,所以这是一个偏执狂导致的硬件性能问题。 描述代码的最佳方式是单线程代码突然被锁定。

3 个答案:

答案 0 :(得分:4)

为什么需要消除低级锁定?你有死锁问题吗?你有性能问题吗?还是扩展问题?锁通常是争用还是无竞争?

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

通常,有几种策略可以减少您获取的互斥锁数量。

首先,只能从单个线程访问的任何内容都不需要互斥锁。

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

第三,大多数平台现在都支持原子写入 - 当单个基本类型(包括指针)都需要保护时,这可以提供帮助。这些工作与数据库中的乐观锁定非常相似。您还可以使用原子写入来创建无锁算法,以替换更复杂的类型,包括Map实现。但是,除非你非常非常好,否则你最好借用别人的调试实现(java.util.concurrent包中包含很多很好的例子) - 在编写你自己的算法时不小心容易引入错误。< / p>

第四,扩大互斥体的范围可以提供帮助 - 或者简单地保持打开互斥锁更长时间,而不是经常锁定和解锁它,或者锁定“更大”的项目 - 对象而不是其中一个属性, 例如。但是,这必须非常谨慎地完成;你可以通过这种方式轻松地引入问题。

答案 1 :(得分:1)

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

如果您有新鲜感,请尝试识别可以并行完成的程序的大型功能,并使用线程池来安排任务。提高效率的诀窍是尽可能避免使用互斥锁,并(重新)编写应用程序代码以避免在高级别上争用资源。

答案 2 :(得分:0)

您可能会发现一些答案herehere有助于您查找在没有显式锁定的情况下以原子方式更新共享状态的方法。