cppreference compiler c++ multithreading c++11 pthreads

compiler - Cómo configurar el tamaño de la pila con C++ 11 std:: thread



c++11 download (5)

Inicialmente, provengo de un fondo de subprocesos de Posix, y me preguntaba cómo se configura el tamaño de pila del std :: thread antes de la construcción, ya que parece que no puedo encontrar ninguna referencia para realizar esa tarea.

No puedes. std::thread no admite esto porque std::thread está estandarizado, y C ++ no requiere que una máquina tenga una pila, y mucho menos una de tamaño fijo.

Los pthreads son más restrictivos en términos del hardware que admiten, y se supone que hay un tamaño fijo de pila por subproceso. (Para que puedas configurar esto)

He estado tratando de familiarizarme con la biblioteca std :: thread en C ++ 11, y he llegado a un escollo.

Inicialmente, provengo de un fondo de subprocesos de Posix, y me preguntaba cómo se configura el tamaño de pila del std :: thread antes de la construcción, ya que parece que no puedo encontrar ninguna referencia para realizar esa tarea.

El uso de pthreads configurando el tamaño de pila se hace así:

void* foo(void* arg); . . . . pthread_attr_t attribute; pthread_t thread; pthread_attr_init(&attribute); pthread_attr_setstacksize(&attribute,1024); pthread_create(&thread,&attribute,foo,0); pthread_join(thread,0);

¿Hay algo similar al usar std :: thread ?

He estado usando la siguiente referencia:

http://en.cppreference.com/w/cpp/thread


Como ya dijo Loki Astari, es extremadamente raro que realmente necesite un tamaño de pila no predeterminado y, por lo general, un error o el resultado de una codificación incorrecta.

  • Si cree que el tamaño de pila predeterminado es demasiado grande para sus necesidades y desea reducirlo, simplemente olvídelo. Ahora, todos los sistemas operativos modernos utilizan memoria virtual / confirmación bajo demanda, lo que significa que la memoria solo se reserva, no se asigna realmente, hasta que se accede a las páginas. Reducir el tamaño de la pila no reducirá su huella de memoria real.

  • Debido a este mismo comportamiento, los sistemas operativos pueden permitirse establecer el tamaño de pila predeterminado en valores muy grandes. Por ejemplo, en un Debian de vainilla, esto es 8MB ( ulimit -s ) que debería ser suficiente para cada necesidad. Si aún logras alcanzar ese límite, mi primera idea sería que tu código es incorrecto, por lo que primero deberías revisarlo y mover las cosas al montón, transformar las funciones recursivas en bucles, etc.

  • Si a pesar de todo esto realmente necesita cambiar el tamaño de pila (es decir, aumentarlo, ya que reducirlo es inútil), en POSIX siempre puede usar setrlimit al inicio de su programa para aumentar el tamaño de pila predeterminado. Claro que esto afectará a todos los subprocesos, pero solo los que lo necesiten usarán la memoria adicional.

  • Por último, pero no menos importante, puedo ver un caso de esquina en el que reducir el tamaño de la pila tendría sentido: si tiene toneladas de subprocesos en un sistema de 32 bits, podrían consumir su espacio de direcciones virtuales (de nuevo, no la memoria real). consumo) hasta el punto de que no tenga suficiente espacio de direcciones disponible para el montón. Una vez más, setrlimit es tu amigo aquí, aunque te aconsejaría cambiar a un sistema de 64 bits para beneficiarse del mayor espacio de direcciones virtuales (y, de todos modos, si tu programa es tan grande, probablemente también te beneficiarás de la RAM adicional).


Encontré esto en el libro de Scott Meyers, Overview of the New C++(C++0x) , ya que es bastante largo. No puedo publicarlo como un comentario, ¿es útil?

También hay una API estándar para acceder a los manejadores específicos de la plataforma detrás de los subprocesos, mutexes, variables de condición, etc. Se supone que estos manejadores son el mecanismo para establecer prioridades de subprocesos, establecer tamaños de pila, etc. (Con respecto a la configuración de tamaños de pila, Anthony Williams señala: "De los sistemas operativos que admiten la configuración del tamaño de la pila, todos lo hacen de manera diferente. Si está codificando para una plataforma específica (de modo que el uso de native_handle estaría bien), entonces podría usar las facilidades de esa plataforma para cambiar pilas. p. ej., en POSIX puede usar makecontext y swapcontext junto con la asignación explícita de una pila, y en Windows puede usar Fibras. Luego, puede usar las instalaciones específicas de la plataforma (p. ej., las banderas del vinculador) para establecer el tamaño de pila predeterminado en algo realmente pequeño, y luego cambia las pilas a algo más grande donde sea necesario. ")


Estaba buscando la respuesta a esto yo mismo ahora.

Parece que si bien std :: thread no admite esto, boost :: thread sí.

En particular, puedes usar boost::thread::attributes para lograr esto:

boost::thread::attributes attrs; attrs.set_size(4096*10); boost::thread myThread(attrs, fooFunction, 42);


También he estado investigando este problema. Para algunas aplicaciones, el tamaño de pila predeterminado no es adecuado. Ejemplos: el programa hace una recursión profunda dependiendo del problema específico que está resolviendo; El programa necesita crear muchos subprocesos y el consumo de memoria es un problema.

Aquí hay un resumen de soluciones (parciales) / soluciones que encontré:

  • g ++ admite una opción -fsplit-stack en Linux. See para obtener más información sobre las pilas divididas. Aquí está el resumen de su sitio web:

El objetivo de las pilas divididas es permitir una pila no contigua que se cultiva automáticamente según sea necesario. Esto significa que puede ejecutar varios subprocesos, cada uno comenzando con una pila pequeña, y hacer que la pila aumente y disminuya según lo requiera el programa.

Nota: -fsplit-stack solo me funcionó después de que empecé a usar el enlazador dorado . Parece que clang ++ también apoyará esta bandera. La versión que probé (clang ++ 3.3) se bloqueó al intentar compilar mi aplicación utilizando el indicador -fsplit-stack .

  • En Linux, establezca el tamaño de la pila ejecutando ulimit -s <size> antes de iniciar su aplicación. size es el tamaño de pila en Kbs. Nota: el comando unlimit -s unlimited no afectó el tamaño de los subprocesos creados con std::thread . Cuando usé ulimit -s unlimited , el hilo principal podría crecer, pero los hilos creados con std::thread tenían el tamaño predeterminado.

  • En Windows que usa Visual Studio, podemos usar el parámetro vinculador /STACK o /STACKSIZE en el archivo de definición del módulo, este es el tamaño predeterminado para todos los subprocesos creados. Vea este enlace para más información. También podemos modificar este parámetro en cualquier archivo ejecutable usando la herramienta de línea de comandos EDITBIN .

  • En Windows usando mingw g ++, podemos usar la opción -Wl,--stack,<size> . Por alguna razón, cuando se usa cygwin g ++, esta bandera solo afecta el tamaño del hilo principal.

Enfoques que no me funcionaron:

  • ulimit -s <size> en OSX. Afecta solo el tamaño del hilo principal. Además, el valor predeterminado de Mac OSX para un tamaño de pila pthread es 512kB.

  • setrlimit solo afecta el tamaño del hilo principal en Linux y OSX. En cygwin, nunca me funcionó, parece que siempre devuelve un error.

Para OSX, la única alternativa parece usar boost::thread lugar de std::thread , pero esto no es bueno si queremos mantener el estándar. Espero que g ++ y clang ++ también sean compatibles con -fsplit-stack en OSX en el futuro.