Question

J'ai un peu de code, que je n'arrive pas à comprendre correctement. Le problème est que le programme est multithread et qu’il contient un peu de code qui doit être synchronisé. J’écris ceci:

lock (lockObject)
{
   if (!Monitor.TryEnter(lockObject))
     Monitor.Wait(lockObject);

   //do stuff...
   Monitor.PulseAll(lockObject);
}
Monitor.Exit(lockObject);

Le problème que j’ai, c’est qu’à un moment donné, tous les threads semblent dormir - quelqu'un peut-il dire pourquoi? Le programme continue de ne pas consommer quasiment aucun processeur, mais aucun travail n’a été accompli. En traçant le programme, j’ai découvert qu’à un moment donné, aucun fil n’était actif mais que beaucoup d’entre eux dormaient. Je connais surtout l’erreur (dans le cas d’un développeur - toujours) de 0,5 m devant le moniteur - mais je ne peux pas la résoudre moi-même… peut-être dans quelques minutes;)

quelqu'un peut-il m'expliquer cela - merci d'avance.

Était-ce utile?

La solution

Existe-t-il une différence entre LockObject et lockObject ? Ce n'est pas clair ...

Cependant! Si ce sont des objets différents, alors tout d'abord: vous ne pouvez pas Attendre sur un verrou que vous n'avez pas ... et TryEnter ne renverra que false si vous spécifiez une temps libre. Qu'est-ce que ce code essaie de faire exactement?

Sans plus de contexte, les objectifs de PulseAll et de Wait ne sont pas tout à fait clairs. par exemple, ici , ils servent à bloquer la file d'attente lorsque il est trop plein ( Wait ), ou relâchez-le quand un espace devient disponible ( PulseAll ), etc. Il est difficile de déboguer du code de thread sans les interactions complètes entre les threads.

Il semble que vous ayez peut-être besoin de:

lock (lockObject)
{
    // do stuff
}

Je peux voir deux problèmes immédiats: Tout d’abord, il n’est pas évident que vous libériez toujours les verrous que vous prenez (c’est-à-dire les exceptions). Essayez simplement d’utiliser lock pour Entrer / Quitter - cela fonctionnera correctement.

Deuxième; si tous les threads appellent Wait ... qui va les réveiller? Qu'attendent-ils pour ? Tel que présenté: oui, ils dormiront tous indéfiniment.

Autres conseils

Je déclare que la première instruction de verrouillage est une faute de frappe et vous vouliez dire lock (lockObject) (minuscule).

Je pense que vous avez un peu mal compris les serrures. Le bloc if dans votre code ne sera jamais vrai. La raison en est que lock (lockObject) s’applique réellement à ce qui suit

Monitor.Enter(lockObject);
try {
...
} finally{ 
Monitor.Exit(lockObject);

Donc, au moment où vous frappez le bloc if, vous possédez déjà le verrou et TryEnter doit toujours réussir.

C'est une configuration étrange. Est-ce que 'LockObject' est identique à 'lockObject'? Ou est-ce une faute de frappe? S'ils sont identiques, votre configuration est redondante, car il n'est pas nécessaire d'appeler Monitor.TryEnter sur quelque chose que vous verrouillez déjà. Si 'LockObject' est un objet différent, pourquoi ne pas déplacer Monitor.Exit vers l'intérieur de l'instruction lock?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top