我正在使用C编程语言和NPTL 2.6开发一个多线程模块化应用程序。为每个插件创建一个POSIX线程。问题是每个线程都有自己的堆栈区域,因为默认的堆栈大小取决于用户的选择,这在某些情况下可能会导致巨大的内存消耗。
为了避免不必要的内存使用,在创建每个线程之前,我使用了类似于此的方法来更改堆栈大小:
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_getstacksize(&attr, &st1);
if(pthread_attr_setstacksize (&attr, MODULE_THREAD_SIZE) != 0) perror("Stack ERR");
pthread_attr_getstacksize(&attr, &st2);
printf("OLD:%d, NEW:%d - MIN: %d\n", st1, st2, PTHREAD_STACK_MIN);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
/* "this" is static data structure that stores plugin related data */
pthread_create(&this->runner, &attr, (void *)(void *)this->run, NULL);编辑I:添加了pthread_create()部分。
这没有像我预期的那样工作,pthread_attr_getstacksize()报告的堆栈大小被更改了,但是应用程序的总内存使用量(来自ps/top/pmap输出)没有改变:
旧:10485760,新:65536-分钟: 16384
当我在启动应用程序之前使用ulimit -s MY_STACK_SIZE_LIMIT时,我达到了预期的结果。
我的问题是:
( 1-)在启动应用程序后(当然是在创建线程之前),是否有任何可移植(在UNIX变体之间)更改(默认)线程堆栈大小的方法?
( 2-)是否可以对每个线程使用相同的堆栈区域?
( 3-)线程是否可以完全禁用堆栈,而不会造成很大的痛苦?
发布于 2009-12-04 06:20:58
2号和3号的答案是“否”和“否”。每个线程都需要一个堆栈(您的局部变量和返回地址在哪里?)而且每个线程都必须是唯一的(否则线程会覆盖对方的局部变量和返回地址,使每个人崩溃)。
至于第一..。set堆栈大小调用正是解决这个问题的答案。我建议您找出一个可接受的大小来创建您的线程,并设置它。
为什么在top里事情看上去不对.top在内存使用方面是一个臭名昭著的骗子。线程创建失败了吗?性能下降和分页到磁盘会增加吗?如果这些问题的答案是否定的,那么我不认为有什么可担心的。
根据以下和上面的一些评论进行更新:
首先,对于您说不需要太多堆栈空间的东西,16‘t还是相当大的。如果你真的想变小,我很想在x86 Linux上说4096或8192。第二,是的,您可以将CPU的堆栈指针设置为其他东西。但是当你使用malloc()或mmap()时,就会占用空间。我不知道您认为设置堆栈指针到其他东西会有什么帮助。尽管如此,如果您确实感到调用main()的线程的堆栈太大(我会说这有点疯狂),并且pthread_attr_setstacksize()没有让您变得足够小(?),那么也许您可以通过调用clone() syscall并根据主线程的堆栈指针指定堆栈,或者其他地方的缓冲区,来查看不可移植的东西,比如创建线程。但是您仍然需要为每个线程提供一个堆栈,我有一种感觉,top仍然会让您失望。也许你的期望值有点高。
发布于 2010-05-15 17:39:37
我也看到了这个问题。还不清楚堆栈是如何计算的,但是“额外”空间是从整个VM中计算出来的,如果您遇到了流程边界,那么您就有麻烦了(即使您没有使用这个空间)。这似乎取决于您正在运行的Linux版本(甚至在2.6系列中),以及您是32位还是64位。
https://stackoverflow.com/questions/1845180
复制相似问题