linux上的进程堆栈大小如何与pthread,fork和exec相关

时间:2010-02-26 07:32:43

标签: stack size exec fork pthreads

我对Linux上进程的堆栈大小有疑问。此堆栈大小是否在链接时确定并在ELF文件中编码?

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

所以我想知道哪些因素会影响某个父进程的fork and exec进程的堆栈大小。是否可以在fork and exec孩子之前的运行时在其父级中设置进程的堆栈大小?
提前谢谢。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

根据man page for fork(),“子进程是用一个线程创建的 - 一个调用fork()的线程。”

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

但是,当调用one of the exec() functions(最终调用execve()来完成实际工作)时,过程映像将替换为新程序。那时,根据堆栈大小软限制(内核2.6.23及更高版本)重新创建堆栈,可以通过调用getrlimit(RLIMIT_STACK, &rlimitStruct)来查看。

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