2010-02-26 18 views
15

Tengo una pregunta sobre el tamaño de la pila de un proceso en Linux. ¿Este tamaño de pila está determinado en el tiempo de vinculación y está codificado en el archivo ELF?¿Cómo se relaciona el tamaño de la pila del proceso en Linux con pthread, fork y el ejecutivo?

Escribí un programa que imprime su tamaño de pila por pthread_attr_getstacksize(&attr, &stacksize);. Y si ejecuto este programa directamente desde un shell, da un valor de aproximadamente 10 MB. Pero cuando lo exec de un hilo que pertenece a un programa de múltiples hilos, da un valor de aproximadamente 2 MB.

Así que quiero saber qué factores afectan el tamaño de la pila de un proceso que es fork and exec -ed desde algún proceso principal. ¿Y es posible establecer el tamaño de pila de un proceso en su padre en tiempo de ejecución antes de fork and exec el hijo?
Gracias de antemano.

Respuesta

20

A medida que la página del manual de pthread_create(3) dice:

"En Linux/x86-32, el tamaño de pila predeterminado para un nuevo hilo es de 2 megabytes", A no ser que se establece el límite de recursos RLIMIT_STACK (ulimit -s): en ese caso, "determina el tamaño de pila predeterminado de los nuevos hilos".

Puede comprobar este hecho mediante la recuperación del valor actual de RLIMIT_STACK con getrlimit(2), como en el siguiente programa:

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

Estos son los resultados cuando se trata de ejecutarlo (compilado a a.out) desde la línea de comandos :

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

Además de esto, Linux crece la pila automáticamente cuando es necesario, pero por supuesto está limitado a estos límites, así como a los límites de espacio de direcciones disponible en las áreas de crecimiento. – nos

+1

nos, solo para el hilo principal, ¿no es así? – osgx

1

Según la man page for fork(), "el proceso hijo se crea con una rosca de la sola que llama tenedor()".

Por lo tanto, el tamaño de pila del subproceso principal para el proceso hijo será el tamaño de pila del subproceso que llama a fork().

Pero cuando se llama al one of the exec() functions (llamando finalmente al execve() para hacer el trabajo real), la imagen del proceso se reemplaza con el nuevo programa. En ese momento, la pila se vuelve a crear de acuerdo con el límite de capacidad del tamaño de pila (núcleo 2.6.23 y posterior), que se puede ver llamando al getrlimit(RLIMIT_STACK, &rlimitStruct).

Usted puede controlar esto antes de llamar a exec estableciendo el límite blando usando setrlimit(RLIMIT_STACK, &rlimitStruct) (siempre que no se trate de aumentar el límite duro o blando establecer el límite superior al límite duro).

Cuestiones relacionadas