Pregunta

Encontré este interesante párrafo en Aumente la documentación del hilo hoy:

void wait(boost::unique_lock<boost::mutex>& lock)

...

  

Efectos: Llamada atómicamente lock.unlock ()   y bloquea el hilo actual. los   el hilo se desbloqueará cuando lo notifique un   llame a este- > notify_one () o   this- > notify_all (), o espuriamente .   Cuando el hilo está desbloqueado (para   cualquiera que sea la razón), la cerradura es   readquirido invocando lock.lock ()   antes de que vuelva la llamada a esperar. los   la cerradura también se recupera invocando   lock.lock () si la función sale con   una excepción.

Entonces, lo que me interesa es el significado de la palabra "espuriamente". ¿Por qué se desbloqueará el hilo por razones espurias? ¿Qué se puede hacer para resolver esto?

¿Fue útil?

Solución

Este artículo de Anthony Williams es particularmente detallado .

  

No se pueden predecir estelas espurias:   son esencialmente al azar de la   punto de vista del usuario. Sin embargo, ellos   comúnmente ocurre cuando la biblioteca de hilos   no puede garantizar de manera confiable que una espera   hilo no perderá una notificación.   Dado que una notificación perdida haría   inutilizar la variable de condición,   la biblioteca de hilos despierta el hilo   de su espera en lugar de tomar el   riesgo.

También señala que no debe usar las sobrecargas timed_wait que toman una duración, y generalmente debe usar las versiones que toman un predicado

  

Ese es el error del principiante, y uno   eso se supera fácilmente con un simple   regla: siempre verifique su predicado en un   bucle cuando espera con una condición   variable. El error más insidioso viene   de timed_wait ().

Este artículo de Vladimir Prus también es interesante.

  

Pero, ¿por qué necesitamos el bucle while?   no podemos escribir:

if (!something_happened)
  c.wait(m);
  

No podemos. Y la razón asesina es que 'esperar' puede   regresar sin ninguna llamada de 'notificar'.   Eso se llama despertar espurio y es   permitido explícitamente por POSIX.   Esencialmente, regrese solo de 'esperar'   indica que los datos compartidos podrían   han cambiado, por lo que los datos deben ser   evaluado de nuevo.

     

Bien, entonces ¿por qué esto aún no se ha solucionado?   La primera razón es que nadie quiere   arreglarlo. Llamada de cierre para 'esperar' en   un bucle es muy deseado por varios   otras razones. Pero esas razones   requieren explicación, mientras que es espuria   wakeup es un martillo que se puede aplicar   a cualquier estudiante de primer año sin   fallar.

Otros consejos

Esta publicación de blog da una razón para Linux, en términos de la llamada al sistema futex que regresa cuando se entrega una señal a un proceso. Desafortunadamente no explica nada más (y de hecho está pidiendo más información).

La entrada de Wikipedia sobre espurias despertares (que parecen ser un concepto de posix, por cierto, no limitado a impulsar) puede interesarle también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top