2009-12-04 84 views
1

我正在开发使用C编程语言的多线程模块化应用程序和NPTL 2.6。对于每个插件,都会创建一个POSIX线程。问题是每个线程都有自己的堆栈区域,因为默认的堆栈大小取决于用户的选择,在某些情况下这可能会导致大量的内存消耗。NPTL默认堆栈大小问题

为了避免不必要的内存使用我用类似于这样创建每个线程之前改变堆栈大小:加入在pthread_create()部分:

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); 

编辑我。

此没有工作的工作如我所料,通过pthread_attr_getstacksize()报告的堆栈大小被改变,但应用(从PS /顶部/ PMAP输出)的总的内存使用情况没有改变:

OLD:10485760 ,NEW:65536 - MIN:16384

当我在启动应用程序之前使用ulimit -s MY_STACK_SIZE_LIMIT时,我达到了预期的结果。

我的问题是:

1)是否有任何便携式(间UNIX变体)的方法来改变启动应用程序(当然创建线程)之前后(默认)线程堆栈大小?

2-)是否可以为每个线程使用相同的堆栈区域?

3-)是否有可能完全禁用堆栈的线程没有太大的痛苦?

+0

愚蠢的问题,但是当你通过'pthread_attr_setstacksize()'修改了堆栈大小后,你是否在实际创建线程时使用了'attr'?我们可以看看你如何调用'pthread_create()'? – 2009-12-04 08:05:09

+0

当然,我已更新我的帖子。 – 2009-12-04 08:30:11

回答

2

#2和#3的答案是否定的。每个线程都需要一个堆栈(你的本地变量和返回地址去哪里?),它们需要是每个线程唯一的(否则线程会覆盖彼此的局部变量并返回地址,使每个人都崩溃)。

至于#1 ...设置的堆栈大小调用正是这个答案。我建议你找出一个可接受的大小来创建你的线程,并设置它。

至于为什么事情看起来不对你在top .... top是一个臭名昭着的关于内存使用情况的骗子。 :-)是否有东西实际上没有被分配或被OOM杀死?线程创作失败了吗?性能是否受到影响并且正在向磁盘分页?如果对这些问题的答案是否定的,那么我认为不必担心太多。

根据以下和部分评论进行更新:
首先,16KB对于您认为不需要太多堆栈空间的东西来说还是相当大的。如果你真的想要变小,我会试图在x86 Linux上说4096或8192。其次,是的,你可以将CPU的堆栈指针设置为其他值。但是当你使用malloc()mmap()时,这将占用空间。我不知道你认为它会如何帮助将堆栈指针设置为别的。也就是说,如果你真的强烈感觉到main()的线程太大(我会说这有点疯狂),并且pthread_attr_setstacksize()不会让你变得足够小(?),那么也许你可以看看通过调用clone()系统调用并根据主线程的堆栈指针或来自其他地方的缓冲区指定堆栈,或类似的东西来创建线程等非便携式东西。但你仍然需要为每个线程堆栈,我有一种感觉top仍然会让你失望。也许你的期望有点高。

+0

这正是他正在做的,请查看他的消息来源的第2行! – Puppe 2009-12-04 06:24:31

+0

是的Puppe,这正是我正在做的。即使堆栈大小可以接受,它也不像我预期的那样工作。至于Q3,我确信有第三方库可以禁用堆栈甚至进程。所以应该有一种方法来模拟堆上的堆栈。 – 2009-12-04 06:35:10

+0

@eyazici - 好吧,堆栈指针是一个CPU寄存器,你可以将它设置为任何你想要的,包括你从malloc()或mmap()得到的东西。但是从你的问题来看,我不知道你在问什么 - 嘿,即使你从其他地方得到它,它仍然是一个堆栈,它仍然会消耗内存等。 – asveikau 2009-12-04 06:37:14

1

我也看到了这个问题。目前还不清楚堆栈是如何计算的,但是“额外”空间是针对您的总虚拟机计算的,并且如果您遇到过程边界时遇到问题(即使您未使用该空间)。它看起来取决于你正在运行的Linux版本(甚至在2.6系列中),以及你是32位还是64位。

+0

它是32位CentOS版本5.3,内核2.6.18 – 2010-05-16 16:29:56