摆脱低级锁定的技术

时间:2020-03-06 14:38:47  来源:igfitidea点击:

我想知道并且需要一种可用于减少低级锁定的策略。
但是这里的问题是,这不是服务器应用程序的新代码(包含成千上万的C ++代码),因此我不能只重写整个内容。

我担心到现在(太晚)可能还没有解决这个问题的方法。但是,我想听听其他人使用的良好模式。

现在有太多的锁,没有太多的冲突,所以这是一个由妄想引起的硬件性能问题。
描述代码的最佳方法是使单线程代码突然被锁定。

解决方案

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

如果我们从头开始,可以尝试确定程序中可以并行执行的大型功能,并使用线程池安排任务。效率的诀窍是尽可能避免互斥,并对应用进行(重新)编码以避免高层争用资源。

为什么需要消除低级锁定?我们有死锁问题吗?我们是否有性能问题?还是规模问题?锁一般是抗争还是无竞争?

我们正在使用什么环境?例如,C ++中的答案将不同于Java中的答案。例如。 Java 6中无竞争的同步块实际上在性能上相对便宜,因此仅升级JRE可能使我们摆脱了要解决的任何问题。通过切换到其他编译器或者锁定库,C ++中可能会有类似的性能提升。

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

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

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

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

第四,扩大互斥锁的范围可以帮助延长互斥锁的时间,而不是不断地对其进行锁定和解锁,或者例如对对象的"较大"项而不是其属性之一进行锁定。但是,必须非常小心地进行此操作。我们可以通过这种方式轻松地引入问题。

当我们寻找无需显式锁定即可自动更新共享状态的方法时,我们可能会在此处和此处找到一些答案。