【发布时间】:2017-07-26 17:30:14
【问题描述】:
据我所知,在基于lock 的并发中,每个线程在进入critical section 之前应该acquire 一个lock,然后在临界区和release 一个锁内执行一些操作,从而允许其他线程继续。
但它的可扩展性如何?
因为无论你有多少核心或线程,它们基本上都是按顺序工作的,由于单锁等待,它们会一个接一个地工作。此类问题通常如何解决?
【问题讨论】:
标签: concurrency
据我所知,在基于lock 的并发中,每个线程在进入critical section 之前应该acquire 一个lock,然后在临界区和release 一个锁内执行一些操作,从而允许其他线程继续。
但它的可扩展性如何?
因为无论你有多少核心或线程,它们基本上都是按顺序工作的,由于单锁等待,它们会一个接一个地工作。此类问题通常如何解决?
【问题讨论】:
标签: concurrency
简短的回答是,它不可扩展至您的系统争用共享锁的程度。线程在锁上序列化,这可能会以您描述的方式严重损害整体吞吐量。
至于如何解决这个问题,这里变得更复杂了,但本质仍然很简单——减少你持有其他线程可能关心的锁的时间。有几种方法可以实现这一点:
这类问题在系统软件开发中经常出现。很长一段时间以来,Linux 内核都拥有所谓的“大内核锁”……对大多数关键内部结构的单一锁。这会导致大量 CPU 出现问题,并最终被移除。
【讨论】:
每个程序都有你所描述的问题直到某一点。克服它的方法是改变处理问题的方式。
随着我们的并发方法越来越好,我们提出了不同的并发模式。例如,在参与者模型中,您甚至不必使用锁定,因为程序的架构允许您完全避免使用共享内存。即使使用传统架构,所使用的锁的数量也会根据您设计程序的方式而发生显着变化。
不过,对于传统的锁定方法,您的代码设计方式应使您的线程不会频繁尝试运行相同的代码块。尽量减少共享内存实例的数量,这样您就不必如此频繁地锁定。
此外,如果您尝试使用不可变数据结构,您会注意到设计并发应用程序的方式会发生变化,并且锁的数量会减少。
【讨论】: