¿Cuándo es pthread_spin_lock lo correcto para usar (sobre, por ejemplo, un pthread mutex)?

4 minutos de lectura

Dado que pthread_spin_lock está disponible, ¿cuándo lo usaría y cuándo no debería usarlo?

es decir, ¿cómo decidiría proteger alguna estructura de datos compartida con un pthread mutex o un pthread spinlock?

La respuesta corta es que un spinlock puede ser mejor cuando planea mantener el bloqueo durante un intervalo extremadamente corto (por ejemplo, para no hacer nada más que incrementar un contador), y se espera que la contención sea rara, pero la operación ocurre con la frecuencia suficiente para ser un posible cuello de botella en el rendimiento. Las ventajas de un spinlock sobre un mutex son:

  1. Al desbloquear, no es necesario verificar si otros subprocesos pueden estar esperando el bloqueo y despertándolos. El desbloqueo es simplemente una sola instrucción de escritura atómica.
  2. Si no se obtiene el bloqueo de inmediato, el subproceso no se duerme, por lo que es posible que pueda obtener el bloqueo con una latencia mucho menor tan pronto como esté disponible.
  3. No hay riesgo de que la caché se contamine al ingresar al kernelspace para dormir o activar otros subprocesos.

El punto 1 siempre se mantendrá, pero los puntos 2 y 3 tienen una utilidad un tanto disminuida si considera que las buenas implementaciones de mutex probablemente girarán un número decente de veces antes de pedir ayuda al kernel.

Ahora, la respuesta larga:

Lo que debe preguntarse antes de usar spinlocks es si estas ventajas potenciales superan una desventaja rara pero muy real: qué sucede cuando el programador interrumpe el subproceso que mantiene el bloqueo antes de que pueda liberar el bloqueo. Por supuesto, esto es raro, pero puede suceder incluso si el bloqueo se mantiene para una sola operación de incremento variable o algo igualmente trivial. En este caso, cualquier otro subproceso que intente obtener el bloqueo seguirá girando hasta que el subproceso que mantiene el bloqueo se programe y tenga la oportunidad de liberarlo. Esto puede que nunca suceda si los subprocesos que intentan obtener el bloqueo tienen prioridades más altas que el subproceso que mantiene el bloqueo. Ese puede ser un caso extremo, pero incluso sin diferentes prioridades en juego, puede haber retrasos muy largos antes de que el propietario del bloqueo vuelva a programarse y, lo peor de todo, una vez que comienza esta situación, puede escalar rápidamente tantos subprocesos, todos con la esperanza de obtenga el bloqueo, comience a girar sobre él, ocupando más tiempo del procesador y retrasando aún más la programación del subproceso que podría liberar el bloqueo.

Como tal, tendría cuidado con los spinlocks… 🙂

El spinlock es un bloqueo de “espera ocupada”. Su principal ventaja es que mantiene el subproceso activo y no provocará un cambio de contexto, por lo que si sabe que solo esperará durante muy poco tiempo (porque su operación crítica es muy rápida), entonces esto puede brindar un mejor rendimiento. que un mutex. Por el contrario, un mutex provocará una menor demanda en el sistema si la sección crítica lleva mucho tiempo y es deseable un cambio de contexto.

TL;DR: Depende.

El método más seguro con un aumento de rendimiento es un híbrido de los dos: un mutex adaptativo.

Cuando su sistema tiene múltiples núcleos, gira durante unos miles de ciclos para capturar el mejor caso de contención baja o nula, luego difiere a un mutex completo para ceder el paso a otros subprocesos para bloqueos contenciosos prolongados.

Ambos POSIX (PTHREAD_MUTEX_ADAPTIVE_NP) y Win32 (SetCriticalSectionSpinCount) tienen mutex adaptables, muchas plataformas no tienen una API spinlock POSIX.

¿Cuando es pthread spin lock lo correcto para usar sobre por ejemplo
sebastien kurz

Spinlock solo tiene interés en el contexto MP. Se utiliza para ejecutar tareas pseudo-atómicas. En el sistema monoprocesador, el principio es el siguiente:

  1. Bloquee el programador (si la tarea trata con interrupciones, bloquee las interrupciones en su lugar)
  2. Haz mi tachuela atómica
  3. Desbloquear el programador

Pero en los sistemas MP no tenemos garantías de que otro núcleo no ejecute otro hilo que podría ingresar a nuestra sección de código. Para evitar esto, se ha creado el bloqueo de giro, su propósito es posponer la ejecución de otros núcleos evitando problemas de concurrencia. La sección crítica se convierte en:

  1. Bloquear el programador
  2. SpinLock (evita la entrada de otros núcleos)
  3. Mi tarea
  4. GirarDesbloquear
  5. Desbloqueo de tareas

Si se omite el bloqueo de tareas, durante una programación, otro subproceso podría intentar ingresar a la sección y se repetirá al 100% de la CPU esperando la próxima programación. Si esta tarea es de alta prioridad, producirá un punto muerto.

¿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