12

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

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

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

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

4

3 回答 3

9

然后在调度程序将所有工作寄存器移入和移出内核时复制所有工作寄存器的空间,但还有什么?

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

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

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

如果我在具有 N 个内核的机器上运行,我应该将线程数保持为 N-1

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

于 2013-02-12T20:13:21.657 回答
4

在设计和实施的所有事情上,您都应该尽可能深思熟虑。

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

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

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

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

于 2013-02-12T20:12:39.380 回答
4

要添加到其他优秀帖子:

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

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

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

于 2013-02-12T20:50:20.087 回答