安全线程堆栈大小?

我正在编写一些产生相当multithreading的代码(目前约为512个,但未来可能会更高)。 每个线程只执行少量操作,因此我希望线程在系统上的开销保持在最低限度。

我使用pthread_attr_setstacksize()设置堆栈大小,我可以从PTHREAD_STACK_MIN获得最小允许堆栈大小。 但我的问题是: PTHREAD_STACK_MIN用于线程堆栈大小是否安全? 我如何计算我需要多少堆栈? 是否有任何隐藏的开销需要添加到我的计算中?

另外,还有其他技术可以用来减少线程在系统上的负担吗?

减少线程堆栈大小不会减少开销(不会降低CPU,内存使用或性能)。 在这方面,您唯一的限制是为平台上的线程提供的总可用虚拟地址空间。

我会使用默认的堆栈大小,直到平台出现问题(如果它发生的话)。 如果出现问题,请尽量减少堆栈使用。 然而,这些将导致真正的性能问题,因为您需要打到堆,或在其他地方设计依赖于线程的分配 。

隐藏的管理费用可能包括:

  • 在堆栈上分配大型数组,例如通过VLA , alloca()或只是简单的静态大小的自动数组。
  • 代码您无法控制或不知道使用模板,工厂类等的后果。但是,如果您没有指定C ++,则不太可能成为问题。
  • 从库标题等导入的代码。这些可能会在版本之间发生变化,并会显着改变其堆栈,甚至是线程使用。
  • 递归。 这也是由于以上几点,考虑像boost::bind ,variadic模板,疯狂的宏,然后只是使用缓冲区或堆栈上的大对象的一般递归。

您还可以设置堆栈大小,操作线程优先级,并根据需要暂停和恢复它们,这将显着地帮助调度程序和系统响应。 Pthreads允许您设置争用范围; LWP和范围调度的性能特征差异很大。

以下是一些有用的链接:

  • 通过线程提高性能
  • linux pthread_suspend

你不应该在那么multithreading附近创建任何东西,你绝对不应该创建一个新线程来执行少量操作。 当且仅当您的现有线程完全饱和并且有更多可用的物理或逻辑关注才能工作时,您应该创建一个新线程。 这对大约10个线程左右的合理当前应用程序施加了硬性限制,即使你在hexacore上运行,你最多只需要12个左右。 这样的设计存在很大缺陷,会使用大量的进程内存,并不会真正提高性能。

至于堆栈大小,你无法真正计算出任意线程需要多少,因为它完全取决于代码运行。 但是,在Visual Studio中,典型的堆栈大小是几兆字节。 您必须发布整个代码以及线程执行的反汇编,以了解要使用的堆栈大小。 只需坚持几兆字节即可。

堆栈帧所需的大小取决于您使用的编译器,基本上您可以尝试猜测自动变量的大小,参数和返回地址的一些开销,保存寄存器等。

您应该考虑它是否可以替代使用线程池 。 由于线程的创建不是免费的。