我对Linux上的进程的堆栈大小有疑问。堆栈大小是在链接时确定的,并且已在ELF文件中进行了编码吗?

我写了一个程序,通过

pthread_attr_getstacksize(&attr, &stacksize);

而且,如果我直接从 shell 运行该程序,则它的值约为10MB。但是,当我从属于多线程程序的线程对它进行exec编码时,它的值约为2MB。

因此,我想知道哪些因素会影响某个父进程通过fork and exec编码的进程的堆栈大小。是否可以在对子进程进行fork and exec之前在运行时在其父进程中设置进程的堆栈大小?

最佳答案

正如pthread_create(3)的联机帮助页所述:

“在Linux/x86-32上,新线程的默认堆栈大小为2 MB”,除非设置了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

10-08 03:46