¿Qué son exactamente los "cierres giratorios"?


108

Siempre me pregunté qué son: cada vez que escucho sobre ellos, imágenes de dispositivos futuristas con forma de volante bailan (¿rodando?) Por mi mente ...

¿Qué son?

Respuestas:


125

Cuando usa bloqueos regulares (mutex, secciones críticas, etc.), el sistema operativo pone su hilo en el estado de ESPERA y se adelanta programando otros hilos en el mismo núcleo. Esto tiene una penalización de rendimiento si el tiempo de espera es realmente corto, porque su hilo ahora tiene que esperar una preferencia para recibir el tiempo de CPU nuevamente.

Además, los objetos del kernel no están disponibles en todos los estados del kernel, como en un controlador de interrupciones o cuando la paginación no está disponible, etc.

Los Spinlocks no causan preferencia, sino que esperan en un bucle ("giro") hasta que el otro núcleo libere el bloqueo. Esto evita que el hilo pierda su cuanto y continúe tan pronto como se libere el bloqueo. El simple mecanismo de spinlocks permite que un kernel lo utilice en casi cualquier estado.

Es por eso que en una máquina de un solo núcleo, un spinlock es simplemente una "desactivación de interrupciones" o "aumento de IRQL" que evita la programación de subprocesos por completo.

Los Spinlocks finalmente permiten que los kernels eviten los "Big Kernel Lock" (un bloqueo adquirido cuando el núcleo ingresa al kernel y se libera al salir) y tienen un bloqueo granular sobre las primitivas del kernel, lo que produce un mejor multiprocesamiento en máquinas de múltiples núcleos y, por lo tanto, un mejor rendimiento.

EDITAR : Surgió una pregunta: "¿Eso significa que debería usar spinlocks siempre que sea posible?" e intentaré responderla:

Como mencioné, los Spinlocks solo son útiles en lugares donde el tiempo de espera anticipado es más corto que un cuanto (lea: milisegundos) y la preferencia no tiene mucho sentido (por ejemplo, los objetos del kernel no están disponibles).

Si se desconoce el tiempo de espera o si está en modo de usuario, los Spinlocks no son eficientes. Consume el 100% del tiempo de CPU en el núcleo en espera mientras verifica si hay un bloqueo de giro disponible. Evita que otros subprocesos se ejecuten en ese núcleo hasta que expire su cuanto. Este escenario solo es factible para ráfagas cortas a nivel de kernel y es poco probable que sea una opción para una aplicación en modo de usuario.

Aquí hay una pregunta sobre SO que aborda eso: Spinlocks, ¿qué tan útiles son?


¿Significa que debería girar bloqueos (en lugar de mutex, sección crítica, etc.) siempre que sea posible?

1
que alguien me corrija si me equivoco, pero un bloqueo giratorio no deshabilita la preferencia (es decir, la reprogramación). por la sencilla razón de que, si el spinlock está esperando un recurso bloqueado por otro proceso, entonces ese segundo proceso debe tener la oportunidad de ejecutarse y liberar el recurso. o bien, ejecutar el segundo proceso requiere adelantarse al primer proceso (de giro).
user1284631

lo que hace spinlock en cambio es que no cambia el estado del proceso de TASK_RUNNING a TASK_INTERRUPTIBLE (que es un estado de suspensión) y, por lo tanto, no guarda todo sobre ese proceso (memoria, caché, etc.). en su lugar, el proceso de giro se adelanta, pero nunca abandona los procesos "programables inmediatamente": se mantiene en la memoria y los otros procesos se ejecutan regularmente hasta que uno de ellos libera el recurso que el control de giro está esperando: en ese momento, el spinlock simplemente regresa y el proceso de hilado puede continuar. espera en un estado siempre TASK_RUNNING.
user1284631

1
tiene razón en eso (vea también esto: linuxjournal.com/article/5833 ), pero el hecho es que bloquear un recurso y deshabilitar las interrupciones, aunque es útil realizarlas conjuntamente, son conceptos que de otra manera no están relacionados. básicamente, desea asegurarse de que no está utilizando un recurso que se encuentra en un estado inconsistente, y es por eso que prueba su bloqueo. deshabilitar las interrupciones (también la apropiación) asegura que sí, nadie se meterá con su resurce mientras lo está tratando. pero, para eso, debes estar seguro de que el recurso es gratuito cuando lo estás adquiriendo.
user1284631

1
(luego deshabilite las interrupciones solo para asegurarse de que ninguna otra tarea se esté adelantando y jugando con el recurso). en UP (uni-procesador), este es siempre el caso: el primer spinlock (y los siguientes) simplemente se otorga, las interrupciones (es decir, la preferencia) se deshabilitan y la tarea que usa el recurso nunca se reemplaza: hace todo lo posible trabajo con el recurso, luego habilite las interrupciones (y, por lo tanto, la preferencia). cuando la preferencia está habilitada, el recurso ya está libre. Básicamente, en UP, no hay contención de spinlock y no hay que esperar . en SMP podría ser.
user1284631

25

Supongamos que un recurso está protegido por un bloqueo, un hilo que desea acceder al recurso necesita adquirir el bloqueo primero. Si el bloqueo no está disponible, el subproceso puede comprobar repetidamente si se ha liberado el bloqueo. Durante este tiempo, el subproceso ocupado espera, verificando el bloqueo, usando la CPU, pero sin realizar ningún trabajo útil. Dicho bloqueo se denomina bloqueo de giro.


2
¡Buena respuesta! +1
Jayesh Bhoi

18

Es pertty mucho un bucle que continúa hasta que se cumple una determinada condición:

while(cantGoOn) {};

1
Y / o while (cantGoOn) {sleep (0)};
Jiminion

@Jiminion, si pones un sleep(0), se adelantaría al hilo, eliminando el propósito de usar un spinlock en primer lugar. si necesita ceder a otros hilos, debe usar un candado regular. (Sé que su comentario es muy antiguo, pero quería evitar que otros lo vieran como una sugerencia).
Sedat Kapanoglu

"Un valor de cero hace que el subproceso ceda el resto de su intervalo de tiempo a cualquier otro subproceso que esté listo para ejecutarse. Si no hay otros subprocesos listos para ejecutarse, la función regresa inmediatamente y el subproceso continúa ejecutándose".
Jiminion


5

Es un tipo de cerradura que está ocupada esperando

Se considera un anti-patrón, excepto para la programación del controlador de muy bajo nivel (donde puede suceder que llamar a una función de espera "adecuada" tenga más sobrecarga que simplemente bloquear por ocupado durante unos pocos ciclos).

Consulte, por ejemplo, Spinlocks en el kernel de Linux .


3

SpinLocks son aquellos en los que el hilo espera hasta que el bloqueo esté disponible. Esto normalmente se usará para evitar la sobrecarga de obtener los objetos del núcleo cuando existe la posibilidad de adquirir el objeto del núcleo dentro de un período de tiempo reducido.

Ex:

While(SpinCount-- && Kernel Object is not free)
{}

try acquiring Kernel object

3

Debería utilizar un bloqueo giratorio cuando crea que es más barato entrar en un bucle de espera ocupado y agrupar un recurso en lugar de bloquearlo cuando el recurso está bloqueado.

El giro puede ser beneficioso cuando los bloqueos son finos y numerosos (por ejemplo, un bloqueo por nodo en una lista vinculada), así como cuando los tiempos de retención de bloqueos son siempre extremadamente cortos. En general, mientras mantiene un bloqueo de giro, se debe evitar el bloqueo, llamar a cualquier cosa que pueda bloquear, mantener más de un bloqueo de giro a la vez, realizar llamadas enviadas dinámicamente (interfaz y virtuales), realizar llamadas enviadas estáticamente en cualquier código que no se tenga. t poseer o asignar memoria.

También es importante tener en cuenta que SpinLock es un tipo de valor, por razones de rendimiento. Como tal, uno debe tener mucho cuidado de no copiar accidentalmente una instancia de SpinLock, ya que las dos instancias (el original y la copia) serían completamente independientes entre sí, lo que probablemente conduciría a un comportamiento erróneo de la aplicación. Si se debe pasar una instancia de SpinLock, se debe pasar por referencia en lugar de por valor.


1

En pocas palabras, spinlock emplea instrucciones de comparación e intercambio atómico (CAS) o de prueba y configuración para implementar un lenguaje seguro para subprocesos sin bloqueo y sin espera. Estas estructuras se escalan bien en máquinas de varios núcleos.


Por definición, un spinlock no se usa para implementar nada sin bloqueo o sin espera.
rdb

0

Es un bucle que gira hasta que se cumple una condición.


0

Bueno, sí, el punto de los bloqueos de giro (frente a las secciones críticas tradicionales, etc.) es que ofrecen un mejor rendimiento en algunas circunstancias (sistemas multinúcleo ...), porque no producen inmediatamente el resto del cuanto del hilo.


0

Spinlock, es un tipo de bloqueo, que no se puede bloquear ni dormir. Cualquier hilo que desee adquirir un bloqueo de giro para cualquier recurso compartido o crítico girará continuamente, desperdiciando el ciclo de procesamiento de la CPU hasta que adquiera el bloqueo del recurso especificado. Una vez que se adquiere el spinlock, intenta completar el trabajo en su cuanto y luego libera el recurso respectivamente. Spinlock es el tipo de bloqueo de mayor prioridad, simplemente puedo decir, es un tipo de bloqueo no preventivo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.