1

我正在使用一个库,它使用 8MB 的默认堆栈大小创建一个 pthread。是否可以以编程方式减少库创建的线程的堆栈大小?我尝试setrlimit(RLIMIT_STACK...)在我的main()函数内部使用,但这似乎没有任何效果。 ulimit -s似乎可以完成这项工作,但我不想在我的程序执行之前设置堆栈大小。

有什么想法我能做什么?谢谢

更新 1:似乎我要放弃使用setrlimit(RLIMIT_STACK,...). 我检查常驻内存并发现它比虚拟内存少很多来设置堆栈大小的方法。这足以让我放弃尝试限制堆栈大小。

4

2 回答 2

1

回答这个问题有几个方面。

首先,如评论中所述,这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,但这会导致您丢失有关何时“内存不足”的信息,并导致程序崩溃。在这样一个受约束的系统上,您可能更喜欢更严格的过度使用会计,但是您必须解决线程堆栈大小问题......

于 2014-07-29T17:08:54.820 回答
1

我觉得你运气不好。如果您使用的库没有提供设置堆栈限制的方法,那么在创建线程后就无法更改它。setrlimit 和 shell 限制会影响主线程的堆栈。

线程是在进程内存空间中创建的,因此在创建线程时分配它们的堆栈。在 Unix 上,我相信堆栈会按需映射到 RAM,因此如果您不需要它(虚拟与常驻内存),您实际上可能不会使用 8 Megs 的 RAM。

于 2014-07-29T17:04:34.080 回答