2010-02-26 5 views
15

Ich habe eine Frage über die Stapelgröße eines Prozesses unter Linux. Wird diese Stapelgröße zur Verknüpfungszeit bestimmt und in der ELF-Datei codiert?Wie ist die Stapelgröße des Prozesses auf Linux im Zusammenhang mit Pthread, fork und exec

Ich schrieb ein Programm, das seine Stack-Größe von pthread_attr_getstacksize(&attr, &stacksize); druckt. Und wenn ich dieses Programm direkt von einer Shell aus starte, ergibt das einen Wert von ca. 10MB. Aber wenn ich exec es von einem Thread, der zu einem Multi-Thread-Programm gehört, gibt es einen Wert von etwa 2 MB.

Also ich möchte wissen, welche Faktoren die Stapelgröße eines Prozesses beeinflussen, der -ed von einigen Elternprozess ist. Und ist es möglich, die Stapelgröße eines Prozesses in seinem Elternteil zur Laufzeit vor fork and exec dem Kind zu setzen?
Vielen Dank im Voraus.

Antwort

20

Da die Manpage pthread_create(3) sagt:

"Unter Linux/x86-32, die Standard-Stack-Größe für einen neuen Thread ist 2 Megabyte", es sei denn die RLIMIT_STACK Ressourcengrenze (ulimit -s) festgelegt ist: in In diesem Fall "bestimmt es die Standard-Stack-Größe der neuen Threads".

Sie diese Tatsache überprüfen können, wie im folgenden Programm mit getrlimit(2), den aktuellen Wert von RLIMIT_STACK durch Abrufen:

#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; 
} 

Diese sind die Ergebnisse bei dem Versuch, es zu laufen (zu a.out kompiliert) von der Kommandozeile :

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

Darüber hinaus wächst Linux den Stack automatisch bei Bedarf - aber Sie sind natürlich begrenzt auf diese Grenzen, sowie Grenzen für den verfügbaren Adressraum in den wachsenden Bereichen. – nos

+1

nos, nur für Hauptthread, oder? – osgx

1

die man page for fork() Laut „der untergeordnete Prozess ist mit einem einzelnen fadeneiner geschaffen, fork() aufgerufen.“

Die Stapelgröße des Hauptthreads für den untergeordneten Prozess ist also die Stapelgröße des Threads, der fork() aufruft.

Aber wenn one of the exec() functions aufgerufen wird (schließlich Aufruf execve(), um die eigentliche Arbeit zu tun), wird das Prozessabbild durch das neue Programm ersetzt. Zu diesem Zeitpunkt wird der Stapel entsprechend dem Softlimit der Stapelgröße (Kernel 2.6.23 und höher) neu erstellt, was durch Aufruf von getrlimit(RLIMIT_STACK, &rlimitStruct) ersichtlich ist.

Sie können diese kontrollieren, bevor exec aufrufen, indem Sie die Soft-Limit Einstellung setrlimit(RLIMIT_STACK, &rlimitStruct) mit (sofern Sie nicht versuchen, die harte Grenze zu erhöhen oder die weiche Grenze höher als die harte Grenze gesetzt).