Mutex locks in C#

489 Views Asked by At

I am studying mutual exclusion in college, and decided to write a few producer/consumer programs. I wrote a busy waiting program, a monitor program, a semaphore program, and a mutex program. They all appear to work correctly; however, the first three programs generally run until the buffer is full/empty, then switch threads and continue the process. The mutex solution as a general rule switches threads every time a value is produced/consumed, although I have tested it and this is not required - each thread can run independently. Also, it will occasionally crash, but then if I run it again, it will be fine. Does anyone know why this runs this way? Am I doing something wrong here? This is my code:

class Program
{
    const int BuffSize = 10;
    char[] Buffer = new char[BuffSize];
    volatile int Avail = 0;
    int ValuesToProduce = 95;
    Mutex _Buffer = new Mutex(false);
    Mutex IsFull = new Mutex(true);
    Mutex IsEmpty = new Mutex(true);

    public void Produce()
    {
        for (int i = 0; i < ValuesToProduce; i++)
        {
            while (Avail == BuffSize)
            {
                Console.WriteLine("Wait Producer:");
                IsFull.WaitOne(1000);
            }

            _Buffer.WaitOne();
            Buffer[i % BuffSize] = (char)(32 + i % 95);
            Avail++;
            Console.WriteLine("Produced: {0}", Buffer[i % BuffSize]);
            _Buffer.ReleaseMutex();

            try
            {
                IsEmpty.ReleaseMutex();
            }
            catch
            {

            }
        }
    }

    public void Consume()
    {
        for (int i = 0; i < ValuesToProduce; i++)
        {
            while (Avail < 1)
            {
                Console.WriteLine("Wait Consumer:");
                IsEmpty.WaitOne(1000);
            }

            _Buffer.WaitOne();
            char c = Buffer[i % BuffSize];
            Avail--;
            Console.WriteLine("Consumed: {0}", Buffer[i % BuffSize]);
            _Buffer.ReleaseMutex();

            try
            {
                IsFull.ReleaseMutex();
            }
            catch
            {

            }
        }
    }
}

class Test
{
    static void Main(string[] args)
    {
        Program program = new Program();
        Thread p = new Thread(new ThreadStart(program.Produce));
        Thread c = new Thread(new ThreadStart(program.Consume));
        p.Start();
        c.Start();
    }
}

Edit:

As proof that it is running through completion, here is a screenshot of the output:

enter image description here

0

There are 0 best solutions below