Concurrency 基于锁的并发的可扩展性

Concurrency 基于锁的并发的可扩展性,concurrency,Concurrency,据我所知,在基于lock的并发中,每个线程都应该在进入关键部分之前获取lock,然后在关键部分内执行一些操作并释放锁,从而允许其他线程继续 但这有多大的可伸缩性 因为无论您有多少个内核或线程,它们基本上都是按顺序工作的,由于单锁等待,它们会一个接一个地工作。这些问题通常是如何解决的?简单的回答是,它的可扩展性不可扩展到您的系统正在争夺共享锁的程度。线程在锁上序列化,这会严重影响总体吞吐量,正如您所描述的那样 至于如何解决这个问题,这是它变得更加复杂的地方,但本质仍然很简单——减少您持有其他线程可

据我所知,在基于
lock
的并发中,每个线程都应该
在进入
关键部分之前获取
lock
,然后在关键部分内执行一些操作并
释放
锁,从而允许其他线程继续

但这有多大的可伸缩性


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

简单的回答是,它的可扩展性不可扩展到您的系统正在争夺共享锁的程度。线程在锁上序列化,这会严重影响总体吞吐量,正如您所描述的那样

至于如何解决这个问题,这是它变得更加复杂的地方,但本质仍然很简单——减少您持有其他线程可能关心的锁的时间。有两种方法可以实现这一点:

  • 减少线程抓住锁的时间长度。这既减少了另一个线程必须等待的可能性,也减少了它们在阻塞时必须等待的时间
  • 将互斥扩展到多个锁。与其只有一个锁,不如单独锁定结构,这样就不太可能有重叠。(但是,这会引起对锁顺序和死锁的关注。)
  • 注意避免完全锁定的方法。实际上,只有在改变共享结构时才需要锁定。因此,您可以避免锁定可以避免突变或共享的位置
这类问题在系统软件开发中经常出现。在相当长的一段时间里,Linux内核拥有所谓的“大内核锁”。。。大多数关键内部结构上的单个锁。这导致大量CPU出现问题,最终被删除


每个程序都有您描述到某一点的问题。你克服它的方法是改变处理问题的方式

随着我们对并发方法的改进,我们提出了不同的并发模式。例如,在参与者模型中,您甚至不必使用锁定,因为程序的体系结构允许您完全避免使用共享内存。即使使用传统的体系结构,所使用的锁的数量也将根据您设计程序的方式发生显著变化

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

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