【问题标题】:Cost of a thread线程的成本
【发布时间】:2013-01-28 06:02:12
【问题描述】:

我了解如何以我选择的语言创建线程,并且我了解互斥锁以及共享数据等的危险,但我确信操作系统如何管理线程以及每个线程的成本。我有一系列相关的问题,最清楚地表明我的理解极限的方法可能是通过这些问题。

生成线程的成本是多少?在设计软件时是否值得担心?创建线程的成本之一必须是它自己的堆栈指针和进程计数器,然后是在调度程序将所有工作寄存器移入和移出内核时复制所有工作寄存器的空间,但还有什么?

一个程序的可用堆栈量是在进程的线程之间平均分配还是先到先得?

我可以在(程序)启动时检查硬件的内核数量吗?如果我在 N 核的机器上运行,我应该将线程数保持在 N-1 吗?

【问题讨论】:

  • 是的。可能是。有时。说真的,如果不了解更多关于什么操作系统、什么语言、什么虚拟机、什么线程库等的详细信息,这个问题是不可能回答的。但简短的回答是要小心过早的优化。除非您达到系统限制或分析器告诉您担心,否则我不会担心。
  • 你是怎么到达N-1的?
  • 一种理想化的世界方式,将一个核心留给“其他任务”,或者留给我所有被锁定的家庭男孩。
  • 灰色 +1。有很多帖子提到了检测内核数量,摆弄亲和力等。我不记得有一个帖子说“我的应用程序性能显着提高了”。

标签: multithreading operating-system resources


【解决方案1】:

添加到其他优秀帖子:

'产生一个线程的成本是多少?在设计软件时是否值得担心?'

如果您的设计选择之一经常做这样的事情。避免此问题的一个好方法是在应用程序启动时使用专用于操作的池和/或应用程序生命周期线程创建一次线程。线程间信令比连续线程创建/终止/销毁要快得多,也更安全/更容易。

关于线程停止、终止、销毁、线程数失控、OOM 故障等问题的帖子数量已成为历史。如果您可以完全避免这样做,那就太好了。

【讨论】:

    【解决方案2】:

    然后在移动时将所有工作寄存器复制到空间 并由调度程序关闭核心,但还有什么?

    一个不太明显的成本是施加在调度程序上的压力,如果它需要处理数千个线程,它可能会开始窒息。内存真的不是问题。通过正确的调整,您可以获得一个“线程”来占用很少的内存,比它的堆栈多一点。这种调整可能很困难(即直接在 linux 下使用 clone(2) 等),但可以做到。

    一个程序可用的堆栈数量是否平均分配给 进程的线程或先到先得

    每个线程都有自己的堆栈,通常您可以控制它的大小。

    如果我在一台有 N 核的机器上运行,我应该保留 线程数到 N-1

    检查内核数量很容易,但取决于环境。但是,仅当您的工作负载包含 CPU 密集型操作且 I/O 很少时,将线程数限制为内核数才有意义。如果涉及 I/O,您可能希望拥有比内核更多的线程。

    【讨论】:

      【解决方案3】:

      您在设计和实施的每件事上都应该尽可能深思熟虑。

      我知道每次创建线程时,Java 线程堆栈占用大约 1MB。 ,所以它们加起来。

      线程对于允许长时间运行的活动发生而不阻止所有其他用户/进程取得进展的异步任务是有意义的。

      线程由操作系统管理。有很多方案,都在操作系统的控制下(例如循环,先到先得等)

      对我来说,为某些活动(例如计算密集型计算、图形、数学等)为每个内核分配一个线程非常有意义,但这不一定是决定因素。我开发的一款应用在生产中使用了大约 100 个活动线程;这不是一台 100 核的机器。

      【讨论】:

      • +1,是的 - 大概,你的 100 个线程需要大量的网络 I/O。
      猜你喜欢
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 2016-01-13
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      相关资源
      最近更新 更多