为什么不使用大量多线程代码?

时间:2015-10-24 00:32:20

标签: multithreading performance asynchronous

异步和其他基于事件的编程范例近来似乎像野火一样蔓延,随着node.js的流行,Python 3.5最近的async改进,以及其他什么。

并不是说我特别介意这个或者我自己已经做了很长时间了,但是我一直试图绕过真正的理由。寻找同步编程的弊端似乎始终如一地预先设定了这样一种观念:"你不能为每个请求提供一个线程"而没有真正限定该声明。

为什么不呢?一个线程可能不是人们能想到的最便宜的资源,但它看起来并不昂贵......#34;。在64位计算机上,我们有足够的虚拟地址空间来处理我们想要的所有线程,除非你的调用链相当深,否则每个线程不一定需要比一个更多的物理RAM。单页*用于堆栈加上内核和libc需要的任何小开销。至于性能,我自己的临时测试表明Linux可以在单个CPU上处理超过100,000个线程创建和每秒拆卸,这几乎不会成为瓶颈。

话虽这么说,但我认为基于事件的编程并不是一个诡计,因为它看起来似乎是允许像lighttpd / nginx这样的HTTP服务器的主要驱动因素在高度并发的表现**。但是,我一直试图找到某种实际的查询原因为什么大多数多线程程序速度较慢而无法找到任何内容。

那么,为什么会这样?

*我的测试似乎表明每个线程实际上需要两个页面。也许TLS正在发生一些污点或其他事情,但它似乎并没有发生太大变化。

**虽然也应该说Apache当时使用的是基于进程的并发而不是基于线程的,这显然会产生很大的不同。

3 个答案:

答案 0 :(得分:2)

如果每个请求都有一个线程,那么在不切换上下文100次的情况下,您不能为100个请求中的每个请求做一些工作。虽然计算机必须做的许多事情随着时间的推移变得越来越快,但是上下文切换仍然很昂贵,因为它会破坏缓存,现代系统比以往更依赖于这些缓存。

答案 1 :(得分:0)

一旦准备好或正在运行的线程数(与事件中待处理的线程数相比)和/或进程超出内核数量,那么这些线程和/或进程将竞争相同的内核,相同的缓存和相同的内存总线。

除非有大量的同步事件要发布,否则我不会看到大规模多线程代码的目的,除了具有大量处理器和内核的超级计算机,并且代码通常是大量多处理,多个内存总线。

答案 2 :(得分:0)

这是一个加载的问题。我随着时间的推移听到了不同的反应,因为我之前与不同的开发者进行过多次谈话。主要是,我的直觉是大多数开发人员讨厌它,因为编写多线程代码更难,有时很容易在脚上不必要地拍摄自己。也就是说,每种情况都不同。有些程序非常适合多线程,就像网络服务器一样。每个线程都可以接受请求并基本上处理它而无需太多外部资源。它有一套程序可以应用于决定如何处理它的请求。它决定如何处理它并将其传递出去。所以它相当独立,可以相当安全地在自己的世界中运作。所以这是一个很好的主题。

其他情况可能不太适合。特别是当您需要共享资源时。事情可以快速发展。即使你做了完美的上下文切换,你仍然可能会遇到竞争条件。然后噩梦就开始了。这种情况在巨大的单片应用程序中经常出现,他们选择使用线程并在开发团队中打开地狱之门。

最后,我认为我们可能不会在日常开发中看到更多的线程,但我们将转向更像世界的事件。随着微服务的出现,我们正在沿着这条路走下去。因此可能会使用更多的线程,但不是以使用框架的开发人员可见的方式。它只是框架的一部分。至少这是我的意见。