2010-02-26 114 views
15

我对Linux上进程的堆栈大小有疑问。这个堆栈大小是否在链接时间确定,并在ELF文件中编码?linux上进程的堆栈大小与pthread,fork和exec有关

我写了一个程序,它打印的堆栈大小为pthread_attr_getstacksize(&attr, &stacksize);。如果我直接从一个shell运行这个程序,它会给出大约10MB的值。但是,当我从属于多线程程序的线程中获得exec时,它给出了大约2MB的值。

所以我想知道哪些因素会影响一个进程的堆栈大小,这是从某个父进程开始的。是否有可能在孩子的fork and exec之前的运行时间在其父级中设置进程的堆栈大小?
在此先感谢。

回答

20

至于pthread_create(3)手册页说:

在Linux/X86-32,对于一个新的线程默认堆栈大小是2兆字节”,除非RLIMIT_STACK资源限制(ulimit -s)设置:在在这种情况下,“它确定了新线程的默认堆栈大小”。

您可以通过getrlimit(2)检索RLIMIT_STACK的当前值检查这一事实,如下面的程序:

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/resource.h> 

int main() 
{ 
    /* Warning: error checking removed to keep the example small */ 
    pthread_attr_t attr; 
    size_t stacksize; 
    struct rlimit rlim; 

    pthread_attr_init(&attr); 
    pthread_attr_getstacksize(&attr, &stacksize); 
    getrlimit(RLIMIT_STACK, &rlim); 
    /* Don't know the exact type of rlim_t, but surely it will 
     fit into a size_t variable. */ 
    printf("%zd\n", (size_t) rlim.rlim_cur); 
    printf("%zd\n", stacksize); 
    pthread_attr_destroy(&attr); 

    return 0; 
} 

这些结果时试图运行它的命令行(编译a.out) :

$ ulimit -s 
8192 
$ ./a.out 
8388608 
8388608 
$ ulimit -s unlimited 
$ ./a.out 
-1 
2097152 
$ ulimit -s 4096 
$ ./a.out 
4194304 
4194304 
+3

除此之外,linux在需要时会自动生成堆栈 - 但是您的目标受限于这些限制,以及可扩展区域中可用地址空间的限制。 – nos 2010-02-26 08:56:05

+1

nos,仅适用于主线程,不是吗? – osgx 2011-08-25 19:43:18

1

根据man page for fork(),“子进程是使用单个线程创建的 - 即称为fork()的子进程”。

因此,子进程的主线程的堆栈大小将是调用fork()的线程的堆栈大小。

但是,当调用one of the exec() functions(最终呼叫execve()做真正的工作)时,过程映像被替换为新程序。此时,根据堆栈大小软限制(内核2.6.23及更高版本)重新创建堆栈,可通过调用getrlimit(RLIMIT_STACK, &rlimitStruct)来查看堆栈大小。

可以在调用exec之前通过使用setrlimit(RLIMIT_STACK, &rlimitStruct)(假设您不尝试增加硬限制或将软限制设置为高于硬限制)来设置软限制来控制此操作。