Détecter les deadlocks en C# / .NET grâce au pattern IDisposable
Par Nicolas Lecrique | Classé dans .NET, Avancé, Intermédiaire | Le 09/02/2011
Tags « .NET • C# • deadlock • Dispose • IDisposable • lock • mutex • RAII • using »5
Détecter les deadlocks en C# / .NET grâce au pattern IDisposable
Si vous êtes développeur en environnement multithread, alors vous vous êtes déjà posé cette question : Où est ce deadlock ? !
Bien sûr, ce deadlock est non-reproductible, il survient chez l’utilisateur, et l’on peut passer des heures à le chercher. Sans jamais être sur d’avoir trouvé LE deadlock qui pose problème !
Vous trouverez dans ce post un exemple de lock qui a pour objectif de
- Pouvoir détecter les deadlocks
- Proposer une syntaxe claire et concise
- Ajouter un overhead minimum en terme de performance à la syntaxe lock C# classique
Petit rappel : qu’est-ce qu’un deadlock ?
Un deadlock (interblocage dans sa version française que personne n’utilise) est la situation dans laquelle 2 threads s’attendent mutuellement. Cas concret :
- Un thread T1 acquiert une ressource R1
- Un thread T2 acquiert une ressource R2
- T1 demande la ressource R2
- T2 demande la ressource R1
Avec un schéma :
Exemple de code provoquant un deadlock
void CreateDeadLock() { Object R1 = new object(); Object R2 = new object(); Thread T1 = new Thread(delegate() { Work(R1, R2); }); Thread T2 = new Thread(delegate() { Work(R2, R1); }); T1.Start(); T2.Start(); } void Work(Object acquire, Object demand) { lock (acquire)//T1 take R1 and T2 take R2 { Thread.Sleep(1000);//To ensure that the ressources are taken lock (demand) { } } }
NB : Bien sûr, les situations réelles sont souvent plus compliquées, impliquant par exemple plus de 2 threads ou des locks implicites (écriture dans un fichier…).