Как размер стека процесса в Linux связан с pthread, fork и exec - PullRequest
15 голосов
/ 26 февраля 2010

У меня есть вопрос о размере стека процесса в Linux. Этот размер стека определяется во время связывания и кодируется в файле ELF?

Я написал программу, которая печатает размер своего стека на pthread_attr_getstacksize(&attr, &stacksize);. И если я запускаю эту программу прямо из оболочки, она дает значение около 10 МБ. Но когда я exec это из потока, который принадлежит многопоточной программе, это дает значение около 2 МБ.

Итак, я хочу знать, какие факторы влияют на размер стека процесса, который fork and exec связан с каким-либо родительским процессом. И возможно ли установить размер стека процесса в его родительском элементе во время выполнения до fork and exec дочернего элемента?
Спасибо заранее.

Ответы [ 2 ]

20 голосов
/ 26 февраля 2010

В качестве справочной страницы для pthread_create (3) говорится:

" В Linux / x86-32 размер стека по умолчанию для нового потока составляет 2 мегабайта ", если не установлено ограничение ресурса RLIMIT_STACK (ulimit -s): в этом случае " определяет размер стека по умолчанию для новых потоков".

Вы можете проверить этот факт, получив текущее значение RLIMIT_STACK с помощью getrlimit (2) , как в следующей программе:

#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 голос
/ 04 мая 2016

Согласно справочной странице для fork () : «Дочерний процесс создается с одним потоком, который вызвал fork ().»

Таким образом, размер стека основного потока для дочернего процесса будет размером стека потока, который вызывает fork ().

Но когда вызывается одна из функций exec () (в конечном итоге вызывается execve () для выполнения реальной работы), образ процесса заменяется новой программой. В это время стек воссоздается в соответствии с мягким ограничением размера стека (ядро 2.6.23 и более поздних версий), которое можно увидеть, вызвав getrlimit (RLIMIT_STACK, & rlimitStruct) .

Вы можете контролировать это перед вызовом exec, устанавливая мягкое ограничение с помощью setrlimit (RLIMIT_STACK, & rlimitStruct) (при условии, что вы не пытаетесь увеличить жесткий предел или установить мягкое предел выше, чем жесткий предел).

...