¿Es seguro el hilo malloc?


¿Es la función malloc() reentrante?

Author: einpoklum, 2009-05-13

11 answers

He leído en alguna parte que si compilas con-pthread, malloc se convierte en hilo seguro. Estoy bastante seguro de que su implementación depende, ya que malloc es ANSI C y los hilos no lo son.

Si estamos hablando de ccg:

Compilar y enlazar con -pthread y malloc () será seguro para subprocesos, en x86 y AMD64.

Http://groups.google.com/group/comp.lang.c.moderated/browse_thread/thread/2431a99b9bdcef11/ea800579e40f7fa4

Otra opinión, más [1]]}

{malloc, calloc, realloc, free, posix_memalign} de glibc-2.2+ son thread safe

Http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2005-07/0323.html

 38
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-05 01:43:12

Pregunta: "es malloc reentrante"?
Respuesta: no, no lo es. Aquí hay una definición de lo que hace que una rutina reentre.

Ninguna de las versiones comunes de malloc le permiten volver a introducirlo (por ejemplo, desde un manejador de señales). Tenga en cuenta que una rutina de reentrada puede no usar bloqueos, y casi todas las versiones de malloc en existencia usan bloqueos (lo que los hace seguros para subprocesos), o variables globales/estáticas (lo que los hace inseguros para subprocesos y no reentrantes).

Todas las respuestas far answer " es malloc thread-seguro?", que es una pregunta completamente diferente. Para esa pregunta la respuesta es depende de su biblioteca de tiempo de ejecución, y posiblemente de las banderas del compilador que use. En cualquier UNIX moderno, obtendrás un malloc seguro para subprocesos por defecto. En Windows, utilice /MT, /MTd, /MD o /MDd flags para obtener la biblioteca de tiempo de ejecución segura para subprocesos.

 91
Author: Employed Russian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-10 15:16:05

Aquí hay un extracto de malloc.c de glibc:

Thread-safety: thread-safe a menos que NO_THREADS esté definido

Asumiendo que NO_THREADS no está definido por defecto, malloc es seguro para subprocesos al menos en linux.

 8
Author: shahkhas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-20 14:50:36

Esta es una pregunta bastante vieja y quiero traer frescura de acuerdo con el estado actual de las cosas.

Sí, actualmente malloc() es thread-safe.

Del Manual de Referencia de la Biblioteca C de GNU de glibc-2.20 [released 2014-09-07]:

void * malloc (size_t size)

Preliminar: MT-Safe/...

... 1.2.2.1 Conceptos de seguridad POSIX:

... Las funciones MT-Safe o Thread-Safe son seguras para llamar en presencia de otros hilos. MT, en MT-Safe, significa Multi Thread.

Ser MT-Safe no implica que una función sea atómica, ni que utilice cualquiera de los mecanismos de sincronización de memoria que POSIX expone a los usuarios. Incluso es posible que llamar a funciones MT-Safe en secuencia haga no produce una combinación MT-Safe. Por ejemplo, tener una llamada de hilo dos funciones MT-Safe una tras otra no garantizan comportamiento equivalente a la ejecución atómica de una combinación de ambos funciones, ya que las llamadas concurrentes en otros hilos pueden interferir en un forma destructiva.

Optimizaciones de todo el programa que podrían integrar funciones en toda la biblioteca las interfaces pueden exponer el reordenamiento inseguro, y por lo tanto realizar la inserción a través de la interfaz de la Biblioteca C de GNU no se recomienda. La documentada MT-El estado de seguridad no está garantizado bajo la optimización de todo el programa. Sin embargo, las funciones definidas en encabezados visibles por el usuario están diseñadas para seguro para la inserción.

 8
Author: likern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-10 13:22:41

Sí, en POSIX.1-2008 malloc es seguro para el hilo.

2.9.1 Hilo-Seguridad

Todas las funciones definidas por este volumen de POSIX.1-2008 será seguro para roscas, excepto que las siguientes funciones1 no tienen por qué ser seguras para roscas.

[ una lista de funciones que no contiene malloc ]

 5
Author: Tanz87,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-04 01:30:01

Si está trabajando con GLIBC, la respuesta es: Sí, PERO.

Específicamente, sí, PERO, por favor, tenga en cuenta que mientras malloc y free son seguros para subprocesos, las funciones de depuración no lo son.

Específicamente, las extremadamente útiles funciones mtrace(), mcheck () y mprobe () no son seguras para subprocesos. En una de las respuestas más cortas y directas que jamás verá de un proyecto GNU, esto se explica aquí:

Https://sourceware.org/bugzilla/show_bug.cgi?id=9939

Tendrá que considerar técnicas alternativas, como ElectricFence, valgrind, dmalloc, etc.

Entonces, si quieres decir, "son las funciones malloc() y free() threadsafe", la respuesta es sí. Pero si quieres decir," es toda la suite malloc/free threadsafe", la respuesta es NO.

 4
Author: breakpoint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-17 18:44:35

Depende de la implementación de la biblioteca de tiempo de ejecución de C que esté utilizando. Si está utilizando MSVC, por ejemplo, entonces hay una opción de compilador que le permite especificar con qué versión de la biblioteca desea compilar (es decir, una biblioteca en tiempo de ejecución que admite subprocesos múltiples al ser segura para la banda de rodadura, o no).

 1
Author: ChrisW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-13 02:32:34

No, no es seguro para hilos. En realidad puede haber una función malloc_lock() y malloc_unlock() disponible en su biblioteca de C. Sé que existen para la biblioteca Newlib. Tuve que usar esto para implementar un mutex para mi procesador, que es multi-threaded en hardware.

 1
Author: sybreon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-13 03:02:28

Malloc y free no son reentrantes, porque utilizan una estructura de datos estática que registra qué bloques de memoria son libres. Como resultado, ninguna función de biblioteca que asigne o libere memoria es reentrada.

 1
Author: user3379688,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-05 07:09:10
 0
Author: Paul Sonier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-13 02:25:09

Respuesta corta: sí, a partir de C11, que es la primera versión del estándar C que incluye el concepto de hilos, malloc y los amigos deben ser seguros para los hilos. Muchos sistemas operativos que incluían ambos subprocesos y un tiempo de ejecución C hicieron esta garantía mucho antes que el estándar C, pero no estoy preparado para jurar a todos . Sin embargo, malloc y los amigos no son y nunca han sido requeridos a ser reentrantes.

Eso significa que es seguro llamar a malloc y free desde múltiples subprocesos simultáneamente y no se preocupe por el bloqueo, siempre y cuando no esté rompiendo ninguna de las otras reglas de asignación de memoria (por ejemplo, llame a free una vez y solo una vez en cada puntero devuelto por malloc). Pero no es seguro llamar a estas funciones desde un manejador de señal que podría haber interrumpido una llamada a malloc o free en el subproceso que maneja la señal. A veces, utilizando una funcionalidad más allá de ISO C, puede garantizar que el subproceso que maneja la señal no interrumpe una llamada a malloc o free, por ejemplo, con sigprocmask y sigpause, pero trata de no hacerlo a menos que no tengas otra opción, porque es difícil hacerlo perfectamente bien.


Respuesta larga con citas: El estándar C agregó un concepto de hilos en la revisión de 2011 (el enlace es al documento N1570, que es la aproximación más cercana al texto oficial del estándar de 2011 que está disponible públicamente sin cargo). En esa revisión, la sección 7.1.4, párrafo 5 dice:

A menos que se indique explícitamente lo contrario en las descripciones detalladas que siguen, las funciones de biblioteca evitarán las carreras de datos de la siguiente manera: Una función de biblioteca no accederá directa o indirectamente a objetos accesibles por subprocesos distintos del subproceso actual a menos que se acceda a los objetos directa o indirectamente a través de los argumentos de la función. Una función de biblioteca no modificará directa o indirectamente objetos accesibles por subprocesos distintos del subproceso actual a menos que se acceda a los objetos directa o indirectamente a través de los argumentos no constantes de la función. Las implementaciones pueden compartir sus propios objetos internos entre subprocesos si los objetos no son visibles para los usuarios y están protegidos contra carreras de datos.

[footnote: Esto significa, por ejemplo, que a una implementación no se le permite usar un objeto estático para fines internos sin sincronización porque podría causar una carrera de datos incluso en programas que no comparten explícitamente objetos entre subprocesos. Del mismo modo, un la implementación de memcpy no está permitida para copiar bytes más allá de la longitud especificada del objeto de destino y luego restaurar los valores originales porque podría causar una carrera de datos si el programa compartiera esos bytes entre subprocesos.]

Según lo entiendo, esta es una forma muy larga de decir que las funciones de biblioteca definidas por el estándar C deben ser seguras para subprocesos (en el sentido habitual: puede llamarlas desde múltiples subprocesos simultáneamente, sin hacer ningún bloqueo usted mismo, siempre y cuando no terminen chocando con los datos pasados como argumentos) a menos que la documentación de una función específica diga específicamente que no lo es.

Entonces, 7.22. 3p2 confirma que malloc, calloc, realloc, aligned_alloc y free en particular son seguros para hilos:

Para determinar la existencia de una carrera de datos, las funciones de asignación de memoria se comportan como si solo accedieran a ubicaciones de memoria accesibles a través de sus argumentos y no otro almacenamiento de duración estática. Sin embargo, estas funciones pueden modificar visiblemente el almacenamiento que asignan o desasignan. Una llamada a free o realloc que desasigne una región p de memoria se sincroniza con cualquier llamada de asignación que asigne la totalidad o parte de la región p. Esta sincronización ocurre después de cualquier acceso de p por la función de desasignación, y antes de cualquier acceso por la función de asignación.

Contraste lo que dice sobre strtok, que no es y nunca ha sido thread-safe, in 7.24.5. 8p6 :

La función strtok no es necesaria para evitar carreras de datos con otras llamadas a la función strtok.

[nota al pie: La función strtok_s se puede usar en su lugar para evitar carreras de datos.]

(comentario sobre la nota al pie: no use strtok_s, use strsep.)

Las versiones anteriores del estándar C no decían nada en absoluto sobre la seguridad de los hilos. Sin embargo, dijeron algo sobre la reentrada, porque las señales siempre han sido parte del estándar C. Y esto es lo que dijeron, volviendo al estándar ANSI C original de 1989 (este documento tiene una redacción casi idéntica, pero una numeración de sección muy diferente de la norma ISO C que salió el año siguiente):

Si se produce [una] señal que no sea el resultado de llamar al abortar o función raise, el comportamiento es indefinido si el controlador de señal llama a cualquier función de la biblioteca estándar que no sea la señal función en sí o se refiere a cualquier objeto con duración de almacenamiento estático que no sea asignando un valor a una variable estática de duración de almacenamiento de tipo volátil sig_atomic_t . Además, si tal llamada a la la función signal resulta en un retorno SIG_ERR, el valor de errno es indeterminado.

Que es una forma larga de decir que las funciones de la biblioteca de C son no requeridas para ser reentradas como regla general. En C11 todavía aparece una redacción muy similar, 7.14.1. 1p5 :

Si se produce [una] señal que no sea el resultado de llamar a la función abort o raise, el comportamiento es indefinido si el controlador de señal se refiere a cualquier objeto con duración de almacenamiento estática o de hilo que no es un objeto atómico libre de bloqueo que no sea asignando un valor a un objeto declarado como sig_atomic_t volátil, o el controlador de señal llama a cualquier función de la biblioteca estándar que no sea la función abort, la función _exit, la función quick_exit, o la función signal con el primer argumento igual al número de señal correspondiente a la señal que causó la invocación del controlador. Además, si tal llamada a la función signal resulta en un retorno SIG_ERR, el valor de errno es indeterminado.

[footnote: Si cualquier señal es generada por un manejador de señal asíncrona, el comportamiento es indefinido.]

POSIX requiere un mucho más largo, pero aún corto en comparación con el tamaño total de la C library, lista de funciones que se pueden llamar de forma segura desde un "manejador de señal asíncrona", y también define con más detalle las circunstancias bajo las cuales una señal podría "ocurrir de otra manera que como resultado de llamar a la función abortar o elevar."Si estás haciendo algo no trivial con señales, probablemente estás escribiendo código destinado a ser ejecutado en un sistema operativo con la naturaleza Unix (a diferencia de Windows, MVS, o algo incrustado que probablemente no tiene una implementación alojada completa de C en el primer lugar), y debe familiarizarse con los requisitos POSIX para ellos, así como con los requisitos ISO C.

 0
Author: zwol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-13 19:38:54