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

namespace MutexSample
{
   class Program
   {
      static int sharedNumber = 42;
      static Mutex localMut = new Mutex();
      static bool isNew;
      static Mutex globalMut = new Mutex(true, "Globalna blokada muteks", out isNew);

      static void Main(string[] args)
      {
         if (!isNew)
         {
            Console.WriteLine("Ta aplikacja została już uruchomiona, następuje wyłączenie dodatkowej instancji...");
            return;
         }

         // dodatkowe wygenerowanie grupy wątków w celu przeprowadzenia operacji na współdzielonych zasobach
         Thread[] workers = new Thread[20];
         for (int i = 0; i < 20; i++)
         {
            Thread worker = new Thread(new ThreadStart(DoWork));
            workers[i] = worker;
            worker.Start();
         }

         foreach (Thread workerThread in workers)
            workerThread.Join();
         Console.WriteLine("Cała praca zakończona, nowa wartość współdzielonego zasobu to {0}", sharedNumber);
         Console.ReadLine();
         globalMut.ReleaseMutex();
      }

      static void DoWork()
      {
         // wątek roboczy oczekuje na uzyskanie dostępu do współdzielonego zasobu
         localMut.WaitOne();

         // modyfikacja współdzielonych zasobów
         // kilka modyfikujących linii kodu, w celu wykazania prawidłowego stanu danych w ramach bloku chronionego przez muteks
         Console.WriteLine("Uzyskuję dostęp do chronionego zasobu...");
         sharedNumber += 2;
         sharedNumber -= 1;

         localMut.ReleaseMutex();
      }
   }
}
