Meine zwei Cent für Mutex und Semaphore in C #

Die Thread-Synchronisierung wird verwendet, um zu verhindern, dass mehrere Threads gleichzeitig auf eine gemeinsam genutzte Ressource zugreifen. Mutex und Semaphore sind zwei der wichtigsten verwandten Konzepte. Lassen Sie uns verstehen, was beide sind und wann wir sie verwenden sollten.

Bevor wir mit unserer Diskussion beginnen, werfen wir einen kurzen Blick auf die Grundkonzepte. Ein Thread ist die kleinste Ausführungseinheit innerhalb eines Prozesses. Im Wesentlichen hilft Ihnen Multithreading dabei, mehrere Aufgaben gleichzeitig auszuführen und damit den Gesamtdurchsatz der Anwendung zu erhöhen.

Ein Mutex ist ein Synchronisationsprimitiv, das prozessübergreifend arbeiten kann, dh für die Synchronisation zwischen Prozessen verwendet werden kann. Im Gegensatz dazu können Sie mit einem Semaphor die Anzahl der Threads begrenzen, die zum gleichen Zeitpunkt Zugriff auf eine gemeinsam genutzte Ressource haben. Im Wesentlichen ist ein Semaphor eine allgemeinere Form eines Mutex.

Ein Semaphor wird verwendet, um die Anzahl der Threads zu begrenzen, die gleichzeitig auf eine gemeinsam genutzte Ressource zugreifen können. Im Wesentlichen wird es verwendet, um die Anzahl der Verbraucher für eine bestimmte gemeinsam genutzte Ressource gleichzeitig zu begrenzen. Sie können Semaphore nutzen, um nicht exklusives Sperren zu implementieren und damit die Parallelität zu begrenzen.

Beachten Sie, dass ein Mutex zum exklusiven Sperren einer gemeinsam genutzten Ressource verwendet wird. Mit anderen Worten, mit einem Mutex können Sie eine sich gegenseitig ausschließende Sperre erwerben. Jeder Thread hätte zu einem bestimmten Zeitpunkt Zugriff auf eine gemeinsam genutzte Ressource. Durch die exklusive Verriegelung wird sichergestellt, dass zu einem bestimmten Zeitpunkt nur ein Thread einen kritischen Abschnitt betreten kann. Ein kritischer Abschnitt kann als Datenstruktur oder Ressource definiert werden, die von mehreren Threads gemeinsam genutzt wird, aber nur ein Thread kann zu einem bestimmten Zeitpunkt darauf zugreifen.

Die System.Threading.Mutex-Klasse stellt einen Mutex dar und die System.Threading.Semaphore-Klasse wird zum Arbeiten mit Semaphoren verwendet. Sie können die WaitOne-Methode für eine Instanz der Mutex-Klasse zum Sperren und die ReleaseMutex-Methode zum Entsperren verwenden.

Mutex mutexObject = new Mutex(false, "Demo");

if (!mutexObject.WaitOne(TimeSpan.FromSeconds(10), false))

     {

             Console.WriteLine("Quitting for now as another instance is in execution...");

               return;

     }

Um ein Semaphor in C # zu erstellen, sollten Sie eine Instanz der Semaphore-Klasse erstellen. Beim Erstellen einer Semaphore-Instanz müssen Sie zwei Argumente an ihren Argumentkonstruktor übergeben. Während das erste Argument verwendet wird, um die Anzahl der anfänglichen Ressourceneinträge anzugeben, wird das zweite Argument verwendet, um die maximale Anzahl gleichzeitiger Ressourceneinträge anzugeben. Beachten Sie, dass Sie für beide Parameter identische Werte angeben sollten, wenn Sie alle Slots für die neu erstellten Threads reservieren möchten. Das folgende Codeausschnitt zeigt, wie Sie ein Semaphor in C # erstellen können.

public static Semaphore threadPool = new Semaphore(3, 5);

Siehe das oben angegebene Code-Snippet. Die obige Anweisung erstellt ein Semaphorobjekt mit dem Namen threadPool, das maximal 5 gleichzeitige Anforderungen unterstützen kann. Beachten Sie, dass die anfängliche Anzahl auf 3 gesetzt ist, wie im ersten Parameter des Konstruktors angegeben. Dies bedeutet, dass 2 Slots für den aktuellen Thread reserviert sind und 3 Slots für andere Threads verfügbar sind. Schreiben wir jetzt etwas Code!

Das folgende Codefragment zeigt, wie Sie 10 Threads mithilfe der im System.Threading-Namespace verfügbaren Thread-Klasse erstellen und starten können. Beachten Sie, wie der ThreadStart-Delegat verwendet wurde.

for (int i = 0; i < 10; i++)

{

   Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

   threadObject.Name = "Thread Name: " + i;

   threadObject.Start();

}

Hier ist der Code der PerformSomeWork-Methode. Dies ist die Methode, die tatsächlich den Code für die Arbeit mit Semaphoren enthält.

private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

Informationen hierzu finden Sie in der oben angegebenen PerformSomeWork-Methode. Die WaitOne-Methode wird für die Semaphore-Instanz aufgerufen, um den aktuellen Thread zu blockieren, bis ein Signal empfangen wird. Die Release-Methode wird auf derselben Instanz aufgerufen, um das Semaphor freizugeben. Hier ist die vollständige Codeliste als Referenz.

class SemaphoreDemo

   {

       public static Semaphore threadPool = new Semaphore(3, 5);

       public static void Main(string[] args)

       {

           for (int i = 0; i < 10; i++)

           {

               Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

               threadObject.Name = "Thread Name: " + i;

               threadObject.Start();

           }

           Console.ReadLine();

       }

       private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

   }