创建线程总是对性能有好处吗?

Posted

技术标签:

【中文标题】创建线程总是对性能有好处吗?【英文标题】:Is it always good for performance to create a thread? 【发布时间】:2020-07-17 20:11:30 【问题描述】:

我最近开始尝试在std::thread 中使用线程,我想知道使用线程是否有任何缺点(特别是在 c++ 中)。是否存在添加更多线程会降低性能的情况?例如,如果我正在创建多个新线程,每个线程都运行一个服务器对象来侦听传入数据,那么为每个服务器实例创建一个新线程是否很糟糕(性能方面)?为什么/为什么不?

【问题讨论】:

"" - 不! 一个例子:***.com/q/17348228/10077 绝对不是!从我的错误中学习。 ***.com/questions/42620323/… 我参与的一个项目,我们为每个 IP 连接创建了一个线程。一位开发人员将其转换为使用select 语句,一个线程将处理多个连接。我们发现引爆点是一个线程处理 50 个连接是当创建一个线程变得比让一个线程管理 51 个连接更好时。所以 1:1 的比例是非常低效的。经验教训:简介、简介、简介、衡量、衡量、衡量。 @Eljay 羞耻选择不再使用。大幅提升性能。 【参考方案1】:

创建太多线程确实会损害性能。

例如,如果您对每个服务器实例都有一个线程,那么您不能为一个服务器实例工作,然后在不切换线程的情况下为另一个服务器实例工作。切换线程是有成本的。

另一个问题是当两个或多个线程尝试访问同一个信息集合时。这可能会导致争用,从而减慢整个系统的速度。现代 CPU 具有多个内核,但内核间资源有限。争夺相同对象的线程可能会使这些内核间总线饱和。

您绝对希望避免在不创建更多线程的情况下无法完成“更多工作”的设计。如果您有三台服务器并且每台服务器都有一个线程,那很好。如果您有数百个客户端并且有一个由十个线程组成的池为它们服务,那很好。如果你有一些特殊的事情要做(比如监控时钟变化)最好由它们自己的线程完成,那也很好。

但一般来说,有很多工作要做的服务器应该将这些工作分配给固定的线程集合。该集合中的线程数应基于系统拥有的内核数、可以同时有效挂起的 I/O 数以及预期的意外延迟量(例如硬页面错误)等因素.

【讨论】:

谢谢,这很有帮助。我可以说,哇!您在我发布问题后的 2 分钟内发布了此答案。这是我第一次提出问题,没想到反应这么快。【参考方案2】:

    创建线程可能会很昂贵。如果您要做的工作量很少,那可能不值得。 This article's measurements 表明创建线程可能需要大约毫秒。

    线程是对 CPU 内核的抽象,虽然您基本上可以创建任意数量的线程,但可用内核的数量是固定的。在某个点之后,您将不会获得额外的加速,因为硬件已经无法提供更多功能了,您实际上可以通过引入更多的簿记和通信开销来slow things down。

    即使您不受硬件并发性的限制,大多数工作负载也并非完全可并行化,并且您将受限于问题的非并行部分。见:https://en.wikipedia.org/wiki/Amdahl%27s_law

【讨论】:

是否有任何关于 Amdal 定律的预期加速和实际加速的图表? 这是我在快速搜索中找到的一个示例:hal.inria.fr/hal-02404346v2/document 虽然我确信这在很大程度上取决于工作负载的结构和运行环境。

以上是关于创建线程总是对性能有好处吗?的主要内容,如果未能解决你的问题,请参考以下文章

爬虫-高性能异步爬虫

高性能异步爬虫

说一说java线程池

说一说java线程池

还不知道线程池的好处?快来了解一下

线程池的好处