Mutex-uri
Un alt instrument de gestionare a sincronizării thread-urilor este clasa Mutex, care se află în namespace-ul System.Threading.
Să luăm exemplul cu operatorul lock din una dintre temele anterioare, în care se utiliza sincronizarea thread-urilor:
int x = 0;
object locker = new(); // obiect placeholder
// pornim cinci thread-uri
for (int i = 1; i < 6; i++)
{
Thread myThread = new(Print);
myThread.Name = $"Thread {i}";
myThread.Start();
}
void Print()
{
lock (locker)
{
x = 1;
for (int i = 1; i < 6; i++)
{
Console.WriteLine($"{Thread.CurrentThread.Name}: {x}");
x++;
Thread.Sleep(100);
}
}
}
Și rescriem acest exemplu folosind mutex-uri:
int x = 0;
Mutex mutexObj = new();
// pornim cinci thread-uri
for (int i = 1; i < 6; i++)
{
Thread myThread = new(Print);
myThread.Name = $"Thread {i}";
myThread.Start();
}
void Print()
{
mutexObj.WaitOne(); // suspendăm thread-ul până la obținerea mutex-ului
x = 1;
for (int i = 1; i < 6; i++)
{
Console.WriteLine($"{Thread.CurrentThread.Name}: {x}");
x++;
Thread.Sleep(100);
}
mutexObj.ReleaseMutex(); // eliberăm mutex-ul
}
Mai întâi, creăm un obiect mutex:
Mutex mutexObj = new Mutex();
Principalele metode pentru sincronizare sunt WaitOne() și ReleaseMutex(). Metoda mutexObj.WaitOne() suspendă execuția thread-ului până când mutex-ul mutexObj este obținut.
Inițial, mutex-ul este liber, așa că este obținut de unul dintre thread-uri.
După ce toate acțiunile sunt finalizate și mutex-ul nu mai este necesar, thread-ul îl eliberează folosind metoda mutexObj.ReleaseMutex(). Apoi, mutex-ul este obținut de unul dintre thread-urile aflate în așteptare.
Astfel, când execuția ajunge la apelul mutexObj.WaitOne(), thread-ul va aștepta până când mutex-ul va fi eliberat. După ce îl obține, va continua să-și execute activitatea.