2009-12-13 18 views
0

J'ai exécuté le code ci-dessous en m'attendant à ce que le débit soit verrouillé la deuxième fois que je verrouille un mutex. Après l'avoir exécuté deux fois, je réalise qu'il peut se bloquer plusieurs fois (en supposant dans le même thread) sans s'arrêter. Comment puis-je changer ce comportement?Comment faire pour que le mutex ne soit pas recusif?

using System; 
using System.Collections.Generic; 
using System.Text; 

using System.Threading; 

namespace Test 
{ 
    class Program 
    { 
     static volatile Mutex mut1 = new Mutex(); 
     static volatile Mutex mut2 = new Mutex(); 
     static void Main(string[] args) 
     { 
      mut1.WaitOne(); Console.WriteLine("1W"); 
      mut2.WaitOne(); Console.WriteLine("2W"); 
      Thread oThread = new Thread(new ThreadStart(fn2)); 
      oThread.Start(); 
      mut1.WaitOne(); Console.WriteLine("1W"); 
      Console.WriteLine("Second"); 
      mut1.ReleaseMutex(); Console.WriteLine("1R"); 
     } 
     static void fn2() 
     { 
      Console.WriteLine("First"); 
      mut2.ReleaseMutex(); Console.WriteLine("2R"); 
      mut1.ReleaseMutex(); Console.WriteLine("1R"); 
     } 
    } 
} 
+0

Les mutex récursifs sont seulement des interblocages moins fréquents que ceux non récursifs. Pourquoi préféreriez-vous avoir la version non récursive? (Je veux dire: si vous écrivez votre programme pour qu'il soit sans interblocage avec la version non récursive, il fonctionnera quand même avec le récursif) –

+0

Non-réponse: Je me suis souvenu que les sections critiques étaient une légère variation sur les mutex , mais ayant vérifié, la version de Windows des sections critiques est récursive aussi. –

Répondre

3

Pour commencer, je ne suis pas sûr que vous comprenez vraiment mutex, vous ne pouvez les libérer dans le contexte (c.-à-fil) dans lequel ils ont été enfermés pour commencer, afin de les utiliser comme une sorte de points de garde fait peu de sens.

Dans ce cas, il peut être plus judicieux d'utiliser semaphores. Mais vous devriez toujours travailler sur ce que vous essayez vraiment de faire :)

using System; 
using System.Collections.Generic; 
using System.Text; 

using System.Threading; 

namespace Test 
{ 
    class Program 
    { 
     static Semaphore sem1 = new Semaphore(1, 1); 
     static Semaphore sem2 = new Semaphore(1, 1); 
     static void Main(string[] args) 
     {   
      sem1.WaitOne(); Console.WriteLine("1W"); 
      sem2.WaitOne(); Console.WriteLine("2W"); 
      Thread oThread = new Thread(new ThreadStart(fn2)); 
      oThread.Start(); 
      sem1.WaitOne(); Console.WriteLine("1W"); 
      Console.WriteLine("Second"); 
      sem1.Release(); Console.WriteLine("1R"); 
     } 
     static void fn2() 
     { 
      Console.WriteLine("First"); 
      sem2.Release(); Console.WriteLine("2R"); 
      sem1.Release(); Console.WriteLine("1R"); 
     } 
    } 
}
+0

Wow ... Bonne prise ... –