En el kernel de Linux, ¿por qué no puedes dormir sosteniendo un spinlock?¿Por qué no puedes dormir sosteniendo un spinlock?
Respuesta
Ejemplo: su controlador se está ejecutando y acaba de sacar un bloqueo que controla el acceso a su dispositivo. Mientras se mantiene el bloqueo, el dispositivo emite una interrupción, lo que hace que se ejecute el manejador de interrupciones. El controlador de interrupciones, antes de acceder al dispositivo, también debe obtener el bloqueo. Sacar un spinlock en un controlador de interrupción es algo legítimo; esa es una de las razones por las que las operaciones de bloqueo de hilado no duermen. Pero, ¿qué sucede si la rutina de interrupción se ejecuta en el mismo procesador que el código que eliminó el bloqueo originalmente? Mientras el controlador de interrupciones está girando, el código no interrumpido no podrá ejecutarse para liberar el bloqueo. Ese procesador girará para siempre.
Evidentemente, esta situación se puede evitar desactivando las interrupciones en las secciones críticas que están protegidas mediante spinlocks. Por ejemplo, Oberon toma este enfoque (Pg. 57). http://e-collection.library.ethz.ch/eserv/eth:26082/eth-26082-02.pdf – gjain
Otra posible explicación es que, en un contexto pre-spinlock preferente está desactivado.
¿Por qué está deshabilitado? – Bandicoot
Aparte de lo que willtate ha mencionado, suponga que un proceso duerme mientras sostiene un spilock. Si el nuevo proceso programado intenta adquirir el mismo spinlock, comienza a girar para que el bloqueo esté disponible. Como el nuevo proceso sigue girando, no es posible programar el primer proceso y, por lo tanto, nunca se libera el bloqueo, lo que hace que el segundo proceso gire para siempre y tenemos un punto muerto.
No es que usted no puede dormir mientras sostiene un bloqueo de giro. Es una idea muy muy mala idea de hacer eso. Citando LDD:
Por lo tanto, la regla principal que se aplica a los spinlocks es que cualquier código debe, mientras se mantiene un spinlock, ser atómico. No puede dormir; de hecho, no puede renunciar al procesador por ningún motivo excepto para interrupciones de servicio (y algunas veces ni siquiera entonces).
Cualquier interbloqueo como el mencionado anteriormente puede provocar un estado irrecuperable. Otra cosa que podría suceder es que el spinlock se bloquea en una CPU, y luego, cuando el hilo duerme, se despierta en la otra CPU, lo que provoca un pánico en el kernel.
Respondiendo comentario de Bandicoot, en un contexto de bloqueo de giro, de tanteo se desactiva sólo en el caso de un solo procesador derecho preferente de compra del núcleo debido a la desactivación de tanteo impide eficazmente razas.
Si el kernel se compila sin CONFIG_SMP, pero se configura CONFIG_PREEMPT, a continuación, el spinlocks simplemente desactiva la prioridad, que es suficiente para evitar cualquier carrera. Para la mayoría de los propósitos, podemos pensar en la apropiación como equivalente a SMP, y no preocuparnos por eso por separado.
http://www.kernel.org/pub/linux/kernel/people/rusty/kernel-locking/index.html
no estoy de acuerdo con la respuesta de William (su ejemplo). Está mezclando dos conceptos diferentes: preferencia y sincronización.
una interrupción Contexto podría adelantarse un contexto de proceso y por lo tanto si hay un recurso compartido por la tanto, tenemos que utilizar
spin_lock_irqsave()
a (1) deshabilitar la IRQ (2) adquirir el bloqueo. En el paso 1, podríamos inhabilitar la opción de interrupción.
Creo que this hilo es muy convincente. Sleep() significa que un hilo/proceso cede el control de la CPU y CONTEXT SWITCH a otro, sin soltar el spinlock, es por eso que está mal.
Estoy de acuerdo, si no estoy equivocado, el problema de William se resuelve mediante el uso de la función spin_lock apropiada para deshabilitar la opción de interrupción. El problema del sueño es diferente, solo debes evitar dormir en la sección crítica del bloqueo de giro, de lo contrario obtendrás un mal rendimiento o un punto muerto. –
El punto clave es en el kernel de Linux, la adquisición de un bloqueo de giro desactivará la preferencia. Por lo tanto, dormir mientras se mantiene un bloqueo de giro podría provocar un punto muerto.
Por ejemplo, el hilo A adquiere un bloqueo de giro. El subproceso A no se adelantará hasta que libere el bloqueo. Siempre que el subproceso A haga su trabajo rápidamente y libere el bloqueo, no hay problema. Pero si el hilo A duerme mientras sostiene el bloqueo, el hilo B podría programarse para ejecutarse, ya que la función de dormir invocará el programador. Y el hilo B también podría adquirir el mismo candado. El subproceso B también desactiva la preferencia y trata de adquirir el bloqueo. Y se produce un punto muerto. El hilo B nunca obtendrá el bloqueo, ya que el hilo A lo mantiene y el hilo A nunca se ejecutará, ya que el hilo B desactiva la preferencia.
¿Y por qué desactivar la preferencia en primer lugar? Supongo que es porque no queremos que los hilos en otros procesadores esperen demasiado tiempo.
si el derecho preferente está deshabilitado, ¿el subproceso B puede programarse para EJECUTAR mientras que el proceso A actual duerme? –
La acción "dormir" invocará al programador, aunque la preferencia está deshabilitada. –
total de acuerdo con Nan Wang. Supongo que el concepto más importante es "prioridad" & "programación" y cómo sucede cuando se adquiere spinlock. cuando se adquiere spinlock, prioridad está deshabilitada (verdadero o no, no sé, pero supongo que es correcto), significa que la interrupción del temporizador no puede anticiparse al titular del spinlock actual, pero el spinlock actual todavía mantiene habilitadas las funciones del kernel para dormir & invoke scheduler & ejecuta "otra tarea". si "otra tarea" pasó a querer adquirir el mismo spinlock que el primer titular del spinlock, aquí viene el problema: dado que la preferencia ya está deshabilitada por el primer titular del spinlock, "otra tarea" invocada activamente por el planificador mediante el primer spinlock titular, no puede ser reemplazado, por lo que su giro siempre toma la CPU, esta es la razón por la cual ocurre un punto muerto.
creo que esto tiene una respuesta mail claridad:
Un proceso no pueda ser substituida ni el sueño mientras se mantiene un comportamiento debido spinlocks spinlock. Si un proceso toma un spinlock y se va a dormir antes de soltarlo. Un segundo proceso (o un manejador de interrupciones) que para agarrar el spinlock estará ocupado. En una máquina uniprocesador, el segundo proceso bloqueará la CPU y no permitirá que el primer proceso se active y libere el spinlock para que el segundo proceso pueda continuar, básicamente es un punto muerto.
- 1. ¿Por qué no se permite "dormir" mientras se sostiene un spinlock?
- 2. ¿Por qué no puedes UnRegisterStartupScript?
- 3. ¿Por qué printf() no imprime nada antes de dormir()?
- 4. ¿Por qué no puedes sobrecargar el '.' operador en C++?
- 5. PHP redirección sosteniendo la escritura
- 6. ¿Por qué no puedes desarrollar juegos XNA en VB.Net?
- 7. ¿Por qué no puedes escribir una expresión de función?
- 8. .NET 4 SpinLock
- 9. ¿Por qué no puedes asignar un int a un entero en un bucle sin llaves?
- 10. Dormir por una duración exacta
- 11. ¿Qué haces cuando no puedes usar ViewState?
- 12. ¿Por qué no puedes poner un objeto const en un contenedor STL?
- 13. Dormir un hilo por un tiempo indefinido en Linux
- 14. x86 spinlock usando cmpxchg
- 15. diferencia entre pthread_spinlock y boost :: smart_ptr :: spinlock?
- 16. SpinLock tirar SynchronizationLockException
- 17. ¿Por qué no puedes convertir un genérico abierto limitado al tipo restringido?
- 18. ¿Por qué no puedes construir un sitio web en modo de lanzamiento?
- 19. ¿Qué eventos pueden activar un dispositivo Android para dormir?
- 20. Dormir en un hilo de C# agrupado
- 21. ¿Qué patrones puedes usar con la herencia de prototipos que no puedes con la clase?
- 22. ¿Qué no puedes hacer en C que puedes hacer en Objective-C?
- 23. Dormir en Fortran
- 24. ¿Por qué no puedes usar 'esto' en los inicializadores de miembros?
- 25. if (0 == '%') echo "WTF, Php, ¿por qué no puedes comparar las cosas sanamente?"
- 26. ¿Por qué no tienes que declarar explícitamente que puedes arrojar algunas excepciones integradas en Java?
- 27. Dormir tarea (System.Threading.Tasks)
- 28. ¿Por qué no puedes llamar funciones abstractas de clases abstractas en PHP?
- 29. ¿Por qué no puedes declarar una estructura estática en C#, pero pueden tener métodos estáticos?
- 30. ¿Por qué no puedes pasar las funciones de MYSQL a las declaraciones de PDO preparadas?
Oversimplified: porque bloqueó a todos los demás con el spinlock, por lo que no pueden programar nada, pero nada a su hilo de espera. – user562374