2009-03-23 7 views
24

Monitor.PulseAll notifie tous les threads en attente dans la file d'attente.La différence entre Monitor.Pulse et Monitor.PulseAll

Monitor.Pulse indique un thread dans la file d'attente. (Le prochain thread en attente)

Seul le thread suivant (un thread) peut acquérir le verrou. Alors, quelle est la difference? Quand dois-je utiliser Pulse par rapport à PulseAll?

+0

Remarque intelligente: 'Pulse' cause un problème,' ​​PulseAll' provoque toutes sortes de problèmes. Vous devriez vraiment utiliser 'ManualResetEvent' ou' AutoResetEvent'. –

Répondre

41

Utilisez PulseAll lorsque vous souhaitez réactiver plusieurs threads, car la condition qu'ils attendent peut être remplie pour plusieurs threads. (Attente est presque toujours associé à une condition - vous devriez généralement tester cette condition dans une boucle while.)

Utilisez Pulse quand vous voulez pour se réveiller un fil, car un seul fil sera effectivement en mesure de faire utile travail.

Pour donner deux analogies:

Imaginez que vous avez une seule imprimante. Une seule personne peut l'utiliser à la fois, donc si vous avez beaucoup de gens qui attendent, vous les envoyez tous dormir - mais vous ne faites que réveiller une personne lorsque l'imprimante est libre. Cela reflète l'utilisation de Pulse.

Imaginez maintenant que vous exploitez un magasin. Pendant que vous êtes fermé, les clients attendent à l'extérieur du magasin. Lorsque vous ouvrez la boutique, vous ne voulez pas simplement réveiller un client - ils peuvent tous entrer maintenant. Cela reflète l'utilisation de PulseAll.

+3

"Lorsque le thread qui a appelé PulseAll libère le verrou, le thread suivant dans la file d'attente prête acquiert le verrou." - Si je ne peux gérer qu'un seul client, pourquoi devrais-je réveiller tout le monde? –

+0

* Si * vous ne pouvez gérer qu'un seul client à la fois, ce n'est pas le cas. Sauf si vous vouliez les laisser tous parcourir, puis faire la queue à la caisse pour payer ... –

+0

(Très peu de magasins permettent seulement un client à la fois :) –

30

Un Monitor a deux files d'attente: la file d'attente et la file d'attente prête. En l'absence de Wait et Pulse, tous les threads qui essaient d'acquérir le verrou vont dans la file d'attente prête. Lorsque le verrou devient disponible, un thread de la file d'attente prête l'acquiert.

Lorsqu'un thread acquiert le verrou puis exécute un Wait, ce thread est placé dans la file d'attente. Il attend un Pulse ou PulseAll, et restera dans la file d'attente jusqu'à ce qu'il reçoive un Pulse, même si d'autres threads de la file d'attente prête acquièrent et libèrent le verrou.

Pulse déplace un thread de la file d'attente vers la file d'attente prête. PulseAll déplace TOUS les threads de la file d'attente dans la file d'attente prête. La clé ici est que les threads dans la file d'attente ne peuvent jamais acquérir le verrou. Ils attendent une impulsion pour les ramener dans la file d'attente prête afin qu'ils puissent acquérir le verrou quand il devient disponible.

Il y a une discussion raisonnablement bonne de Wait and Pulse - au moins un peu pour vous aider à démarrer - here.

+1

Description très claire. –

+1

Merci, très bien expliqué! Pouvez-vous s'il vous plaît clarifier ce qui arrive au thread qui pulse? Est-il déplacé vers la file d'attente prête et peut être programmé immédiatement immédiatement au lieu du thread qui vient de passer de la file d'attente à la file d'attente dy (à cause du Pulse)? –

+3

@RamiYampolsky: Le thread qui fait 'Pulse' conserve le verrou. Il doit appeler 'Wait' ou' Exit' pour libérer le verrou avant que le prochain thread dans la file d'attente prête puisse obtenir le verrou. –

Questions connexes