Note spoiler : la question est la dernière phrase.
En C#, le modèle classique d'utilisation d'une variable de condition est le suivant :
lock (answersQueue)
{
answersQueue.Enqueue(c);
Monitor.Pulse(answersQueue); // condition variable "notify one".
}
et un autre fil :
lock (answersQueue)
{
while (answersQueue.Count == 0)
{
// unlock answer queue and sleeps here until notified.
Monitor.Wait(answersQueue);
}
...
}
c'est un exemple tiré de mon code. si je place le Pulse en dehors de la portée du verrou, il ne compile pas. cependant, c'est la manière correcte : c.f :
http://msdn.microsoft.com/en-us/library/Windows/desktop/ms686903(v=vs.85).aspx et : http://www.installsetupconfig.com/win32programming/threadprocesssynchronizationapis11_7.html (recherche de "inside")
Et en effet, il est idiot de signaler le fil dormant alors que vous êtes encore dans votre section critique. Parce que le fil endormi ne peut pas se réveiller (pas immédiatement), parce qu'il se trouve également à l'intérieur d'une section critique !
Par conséquent, j'espère que l'appel à l'impulsion de .NET ou C# ne fait que marquer l'objet de verrouillage, de sorte que lorsqu'il sort de sa portée, il "impulse" la variable de condition à ce moment-là. Parce que sinon, il y aurait un problème d'optimalité.
Alors comment se fait-il que la conception de l'objet Monitor ait été choisie pour être de cette façon ?
Editar:
J'ai trouvé la réponse dans ce document : http://research.microsoft.com/pubs/64242/implementingcvs.pdf la section "Optimisation du signal et de la diffusion" et la section précédente sur le noyau NT et la façon de rendre les conditions variables en plus des sémaphores, ce qui est la raison de l'introduction des "maudites files d'attente". Maintenant, cela fait de moi un meilleur ingénieur.