使用setrlimit为线程设置堆栈大小

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

任何想法我可以做什么? 谢谢

更新1:似乎我会放弃使用setrlimit(RLIMIT_STACK,...).设置堆栈大小setrlimit(RLIMIT_STACK,...). 我检查了常驻内存,发现它比虚拟内存少得多。 这是我放弃试图限制堆栈大小的充分理由。


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

线程在进程内存空间中创建,因此在创建线程时分配它们的堆栈。 在Unix上,我相信这个堆栈会根据需要映射到内存中,所以如果你不需要内存(虚拟VS驻留内存),你可能不会真正使用8M内存。


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

首先,如评论中所述, pthread_attr_setstacksize是这样做的正确方法。 如果调用pthread_create的库没有办法让你这样做,修复这个库将是理想的解决方案。 如果线程纯粹是库的内部(而不是调用调用应用程序的代码),它应该根据类似于PTHREAD_STACK_MIN + ITS_OWN_NEEDS设置自行设置堆栈大小的首选项。 如果它回调你的代码,它应该让你请求你需要多少堆栈空间。

其次,作为实现细节,glibc使用来自setrlimit / ulimit的堆栈限制来派生由pthread_create创建的线程的堆栈大小。 你可以用这种方式来影响大小,但它不是可移植的,就像你发现的那样,即使在那里也是不可靠的(当你从流程内部调用setrlimit时,它不起作用)。 有可能glibc只在初始化相关代码时探测一次限制,所以我会尝试在main尽早移动setrlimit调用以查看是否有帮助。

最后,线程的堆栈大小可能甚至与您的应用程序无关。 即使堆栈大小为8MB,实际上只有实际被修改的页面(可能是4K或最多8K,除非堆栈中有大数组),实际上是使用物理内存。 其余的只是绑定虚拟地址空间(其中你总是有至少2-3 GB)并且可能会付费。 默认情况下,Linux允许过量使用,因此不会严格执行落实控制,因此glibc请求过多的事实可能无关紧要。 你可以通过写入1/proc/sys/vm/overcommit_memory来使得overcommit检查更加严格,但是这会导致你丢失关于何时“内存不足”的信息,并导致程序崩溃。 在这样一个受限制的系统中,你可能更喜欢更严格的overcommit会计,但是你必须解决线程堆栈大小问题......

链接地址: http://www.djcxy.com/p/80289.html

上一篇: set stack size for threads using setrlimit

下一篇: How to detect the top of the stack in program virtual space