2009-11-03 11 views
103

Hasta donde sé, cada subproceso obtiene una pila distinta cuando el subproceso es creado por el sistema operativo. Me pregunto si cada hilo tiene un montón distinto a sí mismo también.¿Los hilos tienen un montón distinto?

+1

¿Qué biblioteca de plataforma y c? – divegeek

+0

sí, Windows y Linux, c biblioteca – root

+2

Agradable. +1 mantener esas preguntas fundamentales por venir. –

Respuesta

110

No. Todas las discusiones comparten un montón común.

Cada thread has a private stack, que puede agregar y eliminar elementos rápidamente. Esto hace que la memoria basada en pila sea rápida, pero si usa demasiada memoria de pila, como ocurre en la recursión infinita, obtendrá un desbordamiento de pila.

Dado que todos los subprocesos comparten el mismo montón, debe sincronizarse el acceso al asignador/desasignador. Hay varios métodos y bibliotecas para evitar allocator contention.

Algunos idiomas le permiten crear grupos de memoria privados, o montones individuales, que puede asignar a un único hilo.

+0

Eso depende del tiempo de ejecución. – divegeek

+5

Normalmente, los subprocesos comparten recursos, como la memoria, por lo que cualquier implementación de subprocesos sin ideas compartidas compartiría el montón. –

+10

La razón * principal * por la que cada subproceso tiene su propia pila es para que el subproceso realmente pueda hacer algo (como llamar a funciones) ... – Edmund

1

Normalmente, los subprocesos comparten el montón y otros recursos, sin embargo, hay construcciones similares a subprocesos que no lo hacen. Entre estas construcciones parecidas a subprocesos se encuentran los procesos livianos de Erlang y los procesos completos de UNIX (creados con una llamada al fork()). También podría estar trabajando en la concurrencia de máquinas múltiples, en cuyo caso las opciones de comunicación entre hilos son considerablemente más limitadas.

+0

Pensé que tenedor era más como crear un nuevo proceso que acaba de copiar los datos a una nueva ubicación de memoria. –

+2

fork() puede servir en muchos casos de uso donde también se pueden usar subprocesos. Debido al copy-on-write, no hay una diferencia de costo significativa en los sistemas Unix. El caso de uso típico es cuando el trabajador es autónomo (como servidor web) del resto del servicio. Otra posibilidad es comunicarse mediante stdin/out con el hilo/programa principal. fork() es fuerte en Unix, mientras que otras plataformas como Windows prefieren el enhebrado.La razón principal probablemente es que el uso de fork() es mucho más simple y seguro y Unix tiene esta filosofía de simplicidad. Véase, por ejemplo, servidor web apache, con su transición lenta a los hilos. – ypnos

9

De forma predeterminada, C solo tiene un montón único.

Dicho esto, algunos asignadores que son conocedores de subprocesos dividirán el montón para que cada subproceso tenga su propio área para asignar. La idea es que esto debería mejorar la escala del montón.

Un ejemplo de este tipo es Hoard.

+0

Por defecto, C y C++ no tienen múltiples hilos. La especificación 2003 C++ al menos no tiene en cuenta los hilos en su diseño de máquina virtual, por lo que los hilos, en C++, están definidos por la implementación. –

+0

Incluso si diferentes subprocesos tienen diferentes áreas para asignar desde el montón, aún pueden ver los datos asignados por otro subproceso, por lo que los subprocesos aún comparten el mismo montón. –

+1

Actualización: a partir de C++, 11 hilos ya no están definidos en la implementación. – anthropomorphic

3

Cada hilo tiene su propia pila y pila de llamadas.

Cada hilo comparte el mismo montón.

1

En general, todos los subprocesos utilizan el mismo espacio de direcciones y, por lo tanto, suelen tener solo un montón.

Sin embargo, puede ser un poco más complicado. Es posible que esté buscando Thread Local Storage (TLS), pero solo almacena valores únicos.

específicas de Windows: TLS-espacio puede asignarse usando TlsAlloc y liberó usando TlsFree (descripción general here). Nuevamente, no es un montón, solo DWORDs.

Extrañamente, Windows admite múltiples Heaps por proceso. Uno puede almacenar el controlador Heap en TLS. Entonces tendrías algo así como un "Header-Heap local". Sin embargo, los otros subprocesos solo conocen el identificador, aún pueden acceder a su memoria mediante punteros ya que sigue siendo el mismo espacio de direcciones.

EDIT: Algunos asignadores de memoria (específicamente jemalloc en FreeBSD) utilizan TLS para asignar "arenas" a los hilos. Esto se hace para optimizar la asignación de múltiples núcleos al reducir la sobrecarga de sincronización.

+0

> "Extrañamente, Windows admite varios Heaps por proceso.", No es extraño en absoluto, uno podría usar diferentes montones para diferentes tipos de asignaciones, solo agrega más flexibilidad. Por supuesto, siempre puede acceder a VirtualAlloc y crear su propio montón como lo desee. –

5

Depende del sistema operativo. El tiempo de ejecución estándar en Windows y Unices usa un montón compartido en los subprocesos. Esto significa bloquear cada malloc/free.

En Symbian, por ejemplo, cada subproceso viene con su propio montón, aunque los subprocesos pueden compartir punteros a los datos asignados en cualquier montón. El diseño de Symbian es mejor en mi opinión, ya que no solo elimina la necesidad de bloqueo durante alloc/free, sino que también fomenta la especificación limpia de la propiedad de los datos entre hilos. También en ese caso cuando un hilo muere, toma todos los objetos asignados junto con él, es decir, no puede filtrar los objetos que ha asignado, que es una propiedad importante para tener en dispositivos móviles con memoria limitada.

Erlang también sigue un diseño similar donde un "proceso" actúa como una unidad de recolección de basura. Todos los datos se comunican entre procesos mediante copia, a excepción de los blobs binarios que se cuentan como referencia (creo).

2

Depende de qué quiere decir exactamente cuando dice "montón".

Todos los subprocesos comparten el espacio de direcciones, por lo que los objetos asignados en el montón son accesibles desde todos los subprocesos. Técnicamente, las pilas también se comparten en este sentido, es decir, nada le impide acceder a la pila de otros hilos (aunque casi nunca tendría sentido hacerlo).

Por otro lado, hay estructuras de montón utilizadas para asignar memoria. Ahí es donde se realiza toda la contabilidad para la asignación de memoria de montón. Estas estructuras están organizadas de forma sofisticada para minimizar la contención entre los subprocesos, por lo que algunos subprocesos pueden compartir una estructura de montón (una arena), y algunos pueden usar arenas distintas.
Ver siguiente hilo para una excelente explicación de los detalles: How does malloc work in a multithreaded environment?

+0

+1: nadie dijo que la pila (llamada) también se comparte. – user2431763

1

El sistema operativo FreeRTOS, tareas (hilos) comparten el mismo montón, pero cada uno de ellos tiene su propia pila. Esto es muy útil cuando se trata de arquitecturas bajas de RAM de baja potencia, debido a que varios subprocesos pueden acceder/compartir el mismo grupo de memoria, pero esto tiene un pequeño inconveniente, el desarrollador debe tener en cuenta que un mecanismo para sincronizar malloc y libre es necesario, es por eso que es necesario utilizar algún tipo de sincronización de proceso/bloqueo al asignar o liberar memoria en el montón, por ejemplo, un semáforo o un mutex.

Cuestiones relacionadas