簡體   English   中英

Linux 進程的堆棧大小與 pthread、fork 和 exec 有何關系

[英]How is stack size of Linux process related to pthread, fork and exec

我有一個關於 Linux 上進程的堆棧大小的問題。 這個堆棧大小是在鏈接時確定的並在 ELF 文件中編碼嗎?

我編寫了一個程序,它通過以下方式打印其堆棧大小

pthread_attr_getstacksize(&attr, &stacksize);

如果我直接從 shell 運行這個程序,它會給出大約 10MB 的值。 但是當我exec多線程程序的線程exec它時,它給出了大約 2MB 的值。

所以我想知道哪些因素會影響某個進程的堆棧大小,該進程是來自某個父進程的fork and exec -ed。 是否可以在fork and exec子進程之前在運行時在其父進程中設置進程的堆棧大小?

正如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

根據fork()手冊頁,“子進程是使用單個線程創建的 - 調用 fork() 的線程。”

因此,子進程的主線程的堆棧大小將是調用 fork() 的線程的堆棧大小。

但是,當調用exec() 函數之一(最終調用execve()來完成實際工作)時,進程映像將替換為新程序。 這時候會根據棧大小軟限制(內核2.6.23及以后)重新創建棧,調用getrlimit(RLIMIT_STACK, &rlimitStruct)可以看到。

可以在調用 exec 之前通過使用setrlimit(RLIMIT_STACK, &rlimitStruct)設置軟限制來控制這一點(前提是您不要嘗試增加硬限制或將軟限制設置為高於硬限制)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM