web-dev-qa-db-fra.com

Une explication de réveil parasite ressemble à un bug qui ne vaut tout simplement pas la peine d'être corrigé, n'est-ce pas?

Selon l'article de Wikipedia sur Spurious Wakeups

"un thread peut être réveillé de son état d'attente même si aucun thread n'a signalé la variable de condition".

Bien que je connaisse cette `` fonctionnalité '', je n'ai jamais su ce qui l'a réellement provoquée jusqu'à ce que, dans le même article

"Des réveils parasites peuvent sembler étranges, mais sur certains systèmes multiprocesseurs, rendre le réveil des conditions complètement prévisible pourrait ralentir considérablement toutes les opérations de variables de conditions."

Cela ressemble à un bug qui ne mérite tout simplement pas d'être corrigé, n'est-ce pas?

32
James

TL; DR L'hypothèse ("contrat") de réveils parasites est une décision architecturale judicieuse prise pour permettre des implémentations réalistes et robustes du sheduler de fil.

Les "considérations de performances" ne sont pas pertinentes ici, ce ne sont que des malentendus qui se sont répandus en raison de leur mention dans une référence officielle publiée. (Les références faisant autorité peuvent contenir des erreurs, vous savez - il suffit de demander Galileo Galilei ) L'article de Wikipédia conserve la référence à la note que vous avez citée simplement parce qu'elle correspond parfaitement à leurs directives formelles de citer la référence publiée.

Une raison beaucoup plus convaincante pour introduire le concept de réveils parasites est fournie dans cette réponse à SO qui est basée sur des détails supplémentaires fournis dans une (ancienne version) de cet article:

Wikipédia article sur les réveils parasites a cette friandise:

La fonction pthread_cond_wait() sous Linux est implémentée à l'aide de l'appel système futex. Chaque appel système bloquant sous Linux retourne brusquement avec EINTR lorsque le processus reçoit un signal. ... pthread_cond_wait() ne peut pas redémarrer l'attente car il peut manquer un vrai réveil dans le peu de temps où il était en dehors de l'appel système futex ...

Pensez-y ... comme tout code, le planificateur de threads peut subir une panne temporaire en raison de quelque chose d'anormal qui se produit dans le matériel/logiciel sous-jacent. Bien sûr, il faut veiller à ce que cela se produise aussi rare que possible, mais comme il n'existe pas de logiciel 100% robuste, il est raisonnable de supposer que cela peut se produire et faire attention au gracieux récupération au cas où l'ordonnanceur le détecte (par exemple en observant les battements de cœur) manquants.

Maintenant, comment l'ordonnanceur pourrait-il récupérer, en tenant compte du fait que pendant la panne, il pourrait manquer certains signaux destinés à notifier les threads en attente? Si le programmateur ne fait rien, les threads "malchanceux" mentionnés se bloqueront, attendant pour toujours - pour éviter cela, le programmateur enverrait simplement un signal à tous les threads en attente.

Il est donc nécessaire d'établir un "contrat" ​​selon lequel le thread en attente peut être notifié sans raison. Pour être précis, il y aurait une raison - le blackout de l'ordonnanceur - mais comme le thread est conçu (pour une bonne raison) pour ignorer les détails de l'implémentation interne de l'ordonnanceur, il est préférable de présenter cette raison comme "fausse".


Du point de vue du thread, cela ressemble un peu à une loi de Postel (aka principe de robustesse ),

soyez conservateur dans ce que vous faites, libéral dans ce que vous acceptez des autres

L'hypothèse de réveils parasites oblige le thread à être conservateur dans ce qu'il fait: définir la condition lors de la notification aux autres threads, et libéral dans ce qu'il accepte: vérifier la condition sur tout retour d'attente et répétez l'attente s'il n'est pas encore là.

40
gnat

Cela ne vaut pas la peine d'être corrigé, car le code de l'appelant devrait de toute façon utiliser le même traitement (vérifier la condition), afin de gérer la condition de concurrence.

Un traitement pour deux problèmes, que je résume comme suit:

.

Étant donné que cela pourrait se produire plus tard, certains sont allés jusqu'à introduire un réveil parasite dans le contrat:

  • appliquer les bonnes pratiques en exigeant des boucles de prédicat.
  • pour donner une certaine liberté pour l'implémentation du planificateur (y compris une option de récupération d'urgence, comme indiqué par @gnat).

référence SO

1
YvesgereY