Mutex ve Semaphore Farkı
Mutex ve Semaphore, MultiThread yapılarda yardımımıza koşan bir lock yapısı aslında. lock signle thread yapılarda işimizi yapmamızı sağlıyor fakat multiThread yapılarda resource kullanımını thread-safe hale getiriyor.
Bu 2 keyword arasındaki farka gelecek olursak. Mutex, multi thread yapılarda signle thread gibi çalışmayı sağlıyor iken Semaphore multi thread yapıda 1 den fazla threadin thread-safe çalışmasını sağlıyor.
Örnek üzerinde açıklamaya çalışacağım. Dün bir eczaneye gittim ve 3 eczacı çalışıyordu. Bayramın ilk günü olması dolayısıyla hayli kalabalıktı. Hatta o kadar kalabalıktı ki tek sıra ile geliyor ve içeride 3 ayrı bankoya ayrılıyordu. Bir kişi arkamdan öndeki daha az olan sıraya geçince hakkımı yedirmemeye çalıştım ve eczacı sırayı düzenlemeye çalıştı. .Net de ise yardımımıza Semaphore yetişiyor. Bu düzenleme yapan eczacıyı Semaphore olarak düşünebilirsiniz. Bu sayede her bir sıraya izin verilen kadar kişi geçmesini sağlıyor. Yani her threade işini bitirdiği zaman sıradan iş alıyor. Mutex ise tek kişinin çalıştığı bir fırın düşünün. Fırıncı her gelene sırasıyla ekmek veriyor. Kodda da bu şekilde kullandığım için bir nevi kodumu da açıklamış oldum :)
using System;
using System.Threading;
namespace Mutex_Semaphore
{
public class Program
{
private static Mutex mutex = new Mutex();
public static Semaphore pharmacist = new Semaphore(3, 3);
private static Random random = new Random();
public static void Main(string[] args)
{
OpenBakery();
OpenPharmacy();
}
private static void OpenBakery()
{
for (int i = 1; i <= 20; i++)
{
Thread thread = new Thread(new ParameterizedThreadStart(Client));
thread.Start(i);
}
}
public static void Client(object id)
{
Console.WriteLine($”Müşteri {id} sırada { DateTime.Now.ToString(“yyyy.MM.dd HH:mm:ss:fff”)}”);
mutex.WaitOne();
int waiting = random.Next(100, 500);
Console.WriteLine($”Müşteri {id}, {waiting} ms kadar içeride kalıyor { DateTime.Now.ToString(“yyyy.MM.dd HH:mm:ss:fff”)}”);
Thread.Sleep(waiting);
Console.WriteLine($”Müşteri {id} fırından ayrılıyor { DateTime.Now.ToString(“yyyy.MM.dd HH:mm:ss:fff”)}”);
mutex.ReleaseMutex();
}
public static void OpenPharmacy()
{
for (int i = 1; i <= 20; i++)
{
Thread thread = new Thread(new ParameterizedThreadStart(Patient));
thread.Start(i);
}
}
public static void Patient(object id)
{
Console.WriteLine($”Hasta {id} sırada { DateTime.Now.ToString(“yyyy.MM.dd HH:mm:ss:fff”)}”);
pharmacist.WaitOne();
int waiting = random.Next(100, 500);
Console.WriteLine($”Hasta {id}, {waiting} ms kadar içeride kalıyor { DateTime.Now.ToString(“yyyy.MM.dd HH:mm:ss:fff”)}”);
Thread.Sleep(waiting);
Console.WriteLine($”Hasta {id} eczaneden ayrılıyor { DateTime.Now.ToString(“yyyy.MM.dd HH:mm:ss:fff”)}”);
pharmacist.Release(1);
}
}
}
İlk önce fırın örneğimize bakalım.
yukarıda görüldüğü üzere her bir kişinin ekmeği alma süresi yazılmış. Hangi saatte (tabii hızlı olsun diye milisaniye şeklinde yaptım) giriş yaptığı ve ne kadar süre fırında kaldığı yazıyor. Her bir kişi sırayla içeri giriyor ekmeğini alıyor çıkıyor.
Semaphore kodunu çalıştırdığımızda ise aşağıdaki gibi bir ekran çıktısı alacağız.
Yukarıdaki çıktıya bakacak olursak kırmızı dikdörtgen içine alınan kısımda 3 hasta farklı bankolara girerek ilacını almaya çalışıyor. Tabii herkesin işi aynı sürede bitmiyor Hasta 13,19 ve 11 ilacını almaya çalışıyor. 11 ilk çıkan oluyor ve yerine 14 numaralı hasta giriyor. Daha sonra 19 da işini bitiriyor ve çıkıyor. Onun yerine de 1 numara giriyor. Sonra 13 numara da işini bitiriyor. Onun yerine de 2 numara giriyor ve bu şekilde tüm hastalar sırasıyla ilaçlarını alıyor.
İlk medium yazımda umarım faydalı olmuştur :)