0

Si un thread essaye d'acquérir un verrou et qu'il le prend, il doit se mettre en veille et rester endormi jusqu'à ce que le verrou soit libéré. Si un thread libère un verrou (et qu'il est pris par le thread qui l'a créé), il doit réveiller le (s) thread (s). Ma question est, est-ce que cela fait une différence si nous réveillons tous les threads sur l'adresse de verrouillage par rapport à un seul thread sur l'adresse de verrouillage (après la libération de verrouillage)? Et si nous devions réveiller un seul fil, lequel aurait-il du sens de se réveiller, le premier à s'endormir sur l'adresse du verrou?Implémenter les verrous et bloquer les threads

Je peux voir l'avantage de se réveiller un thread, en ce que si nous nous réveillons tous, n-1 peut potentiellement se rendormir. Mais je ne sais pas s'il y a des inconvénients à se réveiller un seul thread.

+2

Si c'est un verrou (mutex, section critique), ce qui pourrait être le point de se réveiller plus d'un thread en attente pour elle? Pourquoi "ils peuvent potentiellement se rendormir", alors que cela semble être la seule chose possible? –

Répondre

2

Je crois que vous avez des fenêtres confusion serrures (mutex, sections critiques) avec les moniteurs .Net (qui en C# peut utiliser le verrouillage mot-clé comme le sucre de syntaxe pour entrer/sortir un bloc.)

de Windows mutex et critique les sections peuvent seulement être entrées et sorties, c'est-à-dire qu'une seule file d'attente leur est associée. Tous les threads dans la file d'attente attendent que le verrou soit libéré et lorsque cela se produit, le thread suivant dans la file d'attente prend le contrôle du verrou et commence à s'exécuter. Tout cela se passe automatiquement. Le thread qui détient actuellement le verrou n'a aucune part dans cela, il ne peut pas choisir de réveiller un ou plusieurs des autres threads attendant que le verrou soit libéré.

Le moniteur de Net possède deux files d'attente: une file d'attente prête et une file d'attente.

La file d'attente prête se comporte exactement comme une file d'attente Win32 Mutex ou Critical Section et est contrôlée à l'aide des méthodes Enter/Leave.

La file d'attente est une file d'attente séparée contrôlée à l'aide des méthodes Wait/Pulse/PulseAll. Ces méthodes ne peuvent être appelées que par le thread qui maintient le moniteur. Lorsqu'un thread appelle Wait, il libère le moniteur et entre dans la file d'attente. Un thread différent peut alors appeler soit Pulse pour déplacer un thread ou Pulse All pour déplacer tous les threads de l'attente à la file d'attente prête (rappelez-vous le thread appel Pulse/PulseAll détient le moniteur.)

D'un point de vue informatique le Moniteur est la seule primitive nécessaire synchroniser les threads (sémaphores, événements, mutex, barrières, etc. peuvent tous être implémentés avec les moniteurs), d'un point de vue pratique Les moniteurs sont utiles comme mutex et pour les situations où les actions doivent être effectuées threads en lock-step. La plupart du temps, cependant, le code est plus lisible lors de l'utilisation d'événements.

Pour en savoir plus:

Wikipedia page about Monitors for the historic/computer science aspect

MSDN Monitor class

+0

Comme l'OP ne mentionne nulle part Net, je me demande pourquoi vous parlez dès le début des moniteurs .Net. Il serait dommage si OP est confus que le moniteur est quelque chose de spécifique à .Net, alors que c'est un concept générique, que vous expliquez autrement très bien. –

+0

@Pavel vous avez peut-être raison. Cela m'a paru comme l'erreur la plus probable étant donné la question. Les moniteurs .Net sont la seule primitive de synchronisation populaire utilisant le mot-clé "lock" et qui peut réveiller d'autres threads. Je peux éditer la réponse pour la rendre claire Monitor est un concept générique qui n'est pas spécifiquement lié à .Net. –