Hasta donde yo sé, cada hilo obtiene una pila distinta cuando el hilo es creado por el sistema operativo. Me pregunto si cada hilo tiene un montón distinto a sí mismo también.
Hasta donde yo sé, cada hilo obtiene una pila distinta cuando el hilo es creado por el sistema operativo. Me pregunto si cada hilo tiene un montón distinto a sí mismo también.
Respuestas:
No. Todos los subprocesos comparten un montón común.
Cada hilo tiene una pila privada , a la que puede agregar y quitar 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 recursividad infinita, obtendrá un desbordamiento de pila.
Dado que todos los subprocesos comparten el mismo montón, el acceso al asignador / desasignador debe sincronizarse. Existen varios métodos y bibliotecas para evitar la contención de asignadores .
Algunos lenguajes le permiten crear grupos privados de memoria, o montones individuales, que puede asignar a un solo hilo.
you will get a stack overflow.
¡Un desbordamiento de pila en Stack Overflow!
De forma predeterminada, C solo tiene un montón.
Dicho esto, algunos asignadores que son conscientes de los subprocesos dividirán el montón para que cada subproceso tenga su propia área para realizar la asignación. La idea es que esto debería mejorar la escala del montón.
Un ejemplo de tal montón es Hoard .
Depende del sistema operativo. El tiempo de ejecución estándar de c en Windows y Unices usa un montón compartido entre subprocesos. Esto significa bloquear todos los archivos 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. En mi opinión, el diseño de Symbian es mejor ya que no solo elimina la necesidad de bloquear durante la asignación / libre, sino que también fomenta la especificación limpia de la propiedad de los datos entre los subprocesos. Además, en ese caso, cuando un hilo muere, toma todos los objetos que asignó junto con él, es decir, no puede filtrar los objetos que ha asignado, que es una propiedad importante en los dispositivos móviles con memoria limitada.
Erlang también sigue un diseño similar en el que un "proceso" actúa como una unidad de recolección de basura. Todos los datos se comunican entre procesos mediante copia, excepto los blobs binarios que se cuentan por referencia (creo).
Depende de a qué te refieres exactamente cuando dices "montón".
Todos los subprocesos comparten el espacio de direcciones, por lo que los objetos asignados al 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, existen estructuras de montón que se utilizan para asignar memoria. Ahí es donde se realiza toda la contabilidad para la asignación de memoria del montón. Estas estructuras están organizadas de manera 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.
Consulte el siguiente hilo para obtener una excelente explicación de los detalles: ¿Cómo funciona malloc en un entorno multiproceso?
Normalmente, los subprocesos comparten el montón y otros recursos, sin embargo, hay construcciones similares a subprocesos que no lo hacen. Entre estas construcciones tipo hilo se encuentran los procesos ligeros de Erlang y los procesos completos de UNIX (creados con una llamada a fork()
). Es posible que también esté trabajando en la simultaneidad de varias máquinas, en cuyo caso sus opciones de comunicación entre subprocesos son considerablemente más limitadas.
En términos generales, todos los subprocesos utilizan el mismo espacio de direcciones y, por lo tanto, suelen tener un solo montón.
Sin embargo, puede resultar un poco más complicado. Es posible que esté buscando Thread Local Storage (TLS), pero solo almacena valores individuales.
Específico de Windows: el espacio TLS se puede asignar usando TlsAlloc y liberarse usando TlsFree (descripción general aquí ). De nuevo, no es un montón, solo DWORD.
Curiosamente, Windows admite varios montones por proceso. Se puede almacenar el identificador de Heap en TLS. Entonces tendrías algo como un "Montón local de subprocesos". Sin embargo, solo el identificador no es conocido por los otros subprocesos, aún pueden acceder a su memoria usando punteros, ya que sigue siendo el mismo espacio de direcciones.
EDITAR : Algunos asignadores de memoria (específicamente jemalloc en FreeBSD) usan 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.
En el sistema operativo FreeRTOS, las tareas (subprocesos) comparten el mismo montón, pero cada una de ellas tiene su propia pila. Esto es muy útil cuando se trata de arquitecturas de bajo consumo de RAM, porque varios subprocesos pueden acceder / compartir el mismo grupo de memoria, pero esto viene con una pequeña trampa, el desarrollador debe tener en cuenta que un mecanismo para sincronizar malloc y se necesita libre, por eso es necesario utilizar algún tipo de sincronización / bloqueo de proceso al asignar o liberar memoria en el montón, por ejemplo un semáforo o un mutex.