¿pthread_mutex_lock contiene instrucción de valla de memoria? [duplicate]

5 minutos de lectura

Hacer pthread_mutex_lock y pthread_mutex_unlock funciones llamada memoria cerca/barrera instrucciones? O haga las instrucciones de nivel inferior como comparar_e_intercambiar Implícitamente tienen barreras de memoria?

avatar de usuario
Maxim Egorushkin

¿Las funciones pthread_mutex_lock y pthread_mutex_unlock llaman a las instrucciones de valla/barrera de memoria?

Lo hacen, así como la creación de subprocesos.

Tenga en cuenta, sin embargo, que hay dos tipos de barreras de memoria: compilador y hardware.

Las barreras del compilador solo evitan que el compilador reordene lecturas y escrituras y especule valores de variables, pero no evitan que la CPU reordene.

Las barreras de hardware evitan que la CPU reordene las lecturas y escrituras. La cerca de memoria completa suele ser la instrucción más lenta, la mayoría de las veces solo necesita operaciones con semántica de adquisición y liberación (para implementar spinlocks y mutexes).

Con subprocesos múltiples, necesita ambas barreras la mayor parte del tiempo.

Cualquier función cuya definición no esté disponible en esta unidad de traducción (y no sea intrínseca) es una compilador barrera de la memoria pthread_mutex_lock, pthread_mutex_unlock, pthread_create también emita una barrera de memoria de hardware para evitar que la CPU reordene lecturas y escrituras.

De Programación con subprocesos POSIX por David R. Butenhof:

Pthreads proporciona algunas reglas básicas sobre la visibilidad de la memoria. Puede contar con todas las implementaciones del estándar para seguir estas reglas:

  1. Cualesquiera que sean los valores de memoria que un subproceso puede ver cuando llama pthread_create también puede ser visto por el nuevo hilo cuando comienza. Cualquier dato escrito en la memoria después de la llamada a pthread_create no necesariamente puede ser visto por el nuevo subproceso, incluso si la escritura se produce antes de que comience el subproceso.

  2. Cualquier valor de memoria que un subproceso pueda ver cuando desbloquea una exclusión mutua, ya sea directamente o esperando una variable de condición, también puede ser visto por cualquier subproceso que más tarde bloquee la misma exclusión mutua. Una vez más, los datos escritos después de que se desbloquee la exclusión mutua pueden no ser necesariamente vistos por el subproceso que bloquea la exclusión mutua, incluso si la escritura se produce antes del bloqueo.

  3. Cualesquiera que sean los valores de memoria que un hilo puede ver cuando termina, ya sea por cancelación, regresando de su función de inicio o llamando pthread_exittambién puede ser visto por el subproceso que se une con el subproceso terminado llamando pthread_join. Y, por supuesto, es posible que el hilo que se une no vea necesariamente los datos escritos después de que finaliza el subproceso, incluso si la escritura se produce antes de la unión.

  4. Cualquier valor de memoria que un subproceso pueda ver cuando señala o transmite una variable de condición también puede ser visto por cualquier subproceso que sea despertado por esa señal o transmisión. Y, una vez más, los datos escritos después de la señal o la transmisión pueden no ser necesariamente vistos por el subproceso que se despierta, incluso si la escritura ocurre antes de que se despierte.

Ver también C++ y más allá de 2012: Herb Sutter – Armas atómicas <> para más detalles.

avatar de usuario
Kaz

Por favor, eche un vistazo a la sección 4.12 de la especificación POSIX.

Las aplicaciones deben garantizar que el acceso a cualquier ubicación de memoria por parte de más de un subproceso de control (subprocesos o procesos) esté restringido de modo que ningún subproceso de control pueda leer o modificar una ubicación de memoria mientras otro subproceso de control puede estar modificándolo. Dicho acceso está restringido mediante funciones que sincronizan la ejecución de subprocesos. y también sincronizar la memoria con respecto a otros hilos. [emphasis mine]

Luego se proporciona una lista de funciones que sincronizan la memoria, además de algunas notas adicionales.

Si eso requiere instrucciones de barrera de memoria en alguna arquitectura, entonces se deben usar.

Sobre compare_and_swap: eso no está en POSIX; verifique la documentación para lo que sea que esté usando. Por ejemplo, IBM define un compare_and_swap función para AIX 5.3. que no tiene semántica de barrera de memoria completa La nota de documentación dice:

Si se usa compare_and_swap como una primitiva de bloqueo, inserte un isync al comienzo de cualquier sección crítica.

De esta documentación podemos adivinar que IBM compare_and_swap tiene semántica de liberación: ya que la documentación no requiere una barrera para el final de la sección crítica. El procesador de adquisición necesita emitir un isync para asegurarse de que no está leyendo datos obsoletos, pero el procesador de publicación no tiene que hacer nada.

A nivel de instrucción, algunos procesadores tienen comparación e intercambio con ciertas garantías de sincronización, y otros no.

  • Buena referencia a POSIX, no sabía que POSIX especificaba la lista exacta de funciones para eso. +1

    – Máximo Egorushkin

    10 de junio de 2014 a las 15:24

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad