基于锁的并发性的可伸缩性

时间:2017-03-06 18:02:36

标签: concurrency

据我所知,在基于lock的并发中,每个帖子在acquire之前应lock critical section,然后在关键部分内执行一些操作{{1一个锁,从而允许其他线程继续。

但这有多可耻?

因为无论你拥有多少个核心或线程,它们基本上会按顺序工作,由于单锁等待而一个接一个。这些问题通常如何解决?

2 个答案:

答案 0 :(得分:0)

简短的回答是,可扩展到您的系统在共享锁上竞争的程度。线程序列化锁定,这可能会严重影响整体吞吐量,完全按照您描述的方式。

至于如何解决这个问题,这就是它变得更复杂的地方,但实质上仍然很简单 - 减少你持有其他线程可能关心的锁的时间。有几种方法可以实现这一目标:

  • 减少线程锁定锁定的时间长度。这降低了另一个线程必须等待的可能性以及它们在阻塞时必须等待的时间。
  • 在多个锁上传播互斥。您可以单独锁定结构,而不是只有一个锁,因此重叠的可能性较小。 (但这引入了对锁定顺序和死锁的担忧。)
  • 避免完全锁定的方法。当你改变共享结构时,你真的只需要锁定。因此,您可以避免锁定在何处可以避免突变或共享。

这类问题在系统软件开发中出现了很多。很长一段时间以来,Linux内核都被称为“大内核锁定”......对大多数关键内部结构进行单一锁定。这会导致大量CPU出现问题,并最终被删除。

https://kernelnewbies.org/BigKernelLock

答案 1 :(得分:0)

每个程序都有你在某一点上描述过的问题。你克服它的方法是改变你解决问题的方式。

随着我们的并发方法越来越好,我们提出了不同的并发模式。例如,在actor模型中,您甚至不必使用锁定,因为程序的体系结构允许您完全避免使用共享内存。即使使用传统架构,根据您设计程序的方式,使用的锁数也会发生显着变化。

对于传统的锁定方法,设计代码的方式是线程不经常尝试运行相同的代码块。尽量保持共享内存实例的数量不变,这样就不必频繁锁定。

此外,如果您尝试使用不可变数据结构,您会注意到您设计并发应用程序的方式将发生变化,锁定量将会减少。