回答这个问题有几个方面。
首先,如评论中所述,这pthread_attr_setstacksize
是正确的做法。如果库调用pthread_create
没有办法让您这样做,那么修复库将是理想的解决方案。如果线程纯粹是库内部的(不是从调用应用程序调用代码),它真的应该根据类似PTHREAD_STACK_MIN + ITS_OWN_NEEDS
. 如果它回调你的代码,它应该让你请求你需要多少堆栈空间。
其次,作为一个实现细节,glibc 使用来自setrlimit
/的堆栈限制ulimit
来导出由pthread_create
. setrlimit
您也许可以通过这种方式影响大小,但它不是可移植的,而且正如您所发现的那样,即使在那里也不可靠(当您从进程本身调用时它不起作用)。glibc 可能仅在首次初始化相关代码时才探测一次限制,因此我会尝试setrlimit
尽早将调用移入main
以查看这是否有帮助。
最后,线程的堆栈大小甚至可能与您的应用程序无关。即使堆栈大小为 8MB,也只有实际修改过的页面(可能是 4k 或最多 8k,除非堆栈上有大数组)实际上使用物理内存。其余的只是占用虚拟地址空间(其中您始终至少有 2-3 GB)并可能提交费用。默认情况下,Linux 启用过度使用,因此不会严格执行提交费用,因此 glibc 请求过多的事实甚至可能无关紧要。你可以通过写一个1
到/proc/sys/vm/overcommit_memory
,但这会导致您丢失有关何时“内存不足”的信息,并导致程序崩溃。在这样一个受约束的系统上,您可能更喜欢更严格的过度使用会计,但是您必须解决线程堆栈大小问题......