用PV操作解决经典进程同步问题 C#实现




在C#中,用于同步的主要是Mutex类与Semaphore类。位于System.Threading命名空间中。

在这两个种对象的方法中,P操作对应的是WaitOne()方法,V操作对应的是ReleaseMutex()与Release()方法。

下面是用C#解决几大PV操作经典问题及其变形的代码。


一、生产者消费者问题

1.最简单的情况:一个生产者,一个消费者,共用一个缓冲区进行生产消费。 

源代码:

using System;
using System.Threading;

namespace OS
{
    class Program
    {
        static Mutex mutex = new Mutex();
      
        static void Main(string[] args)
        {
           // int[] buffer;
            new Thread(new ThreadStart(Producer)).Start();
            new Thread(new ThreadStart(Customer)).Start();
            Console.Read();
        }

        private static  void Producer()
        {
            while (true)
            {
                mutex.WaitOne();
                Console.WriteLine("Producer is working!");
                mutex.ReleaseMutex();
                Thread.Sleep(400);
            }
        }

        private static  void  Customer()
        {
            while (true)
            {
                mutex.WaitOne();
                Console.WriteLine("customer is working");
                mutex.ReleaseMutex();
                Thread.Sleep(400);
            }
        }
    }
}




2.现在稍微复杂一些,生产者与消费者共用一个大小为n的环形缓冲区。本例中n取10.

源代码:

using System;
using System.Threading;

namespace OS
{
    class Program
    {
        static Mutex mutex = new Mutex();
        static Semaphore empty = new Semaphore(10,10);
        static Semaphore full = new Semaphore(0,10);
        static int[] buffer = new int[10];
        static Random rand = new Random();

        static void Main(string[] args)
        {
            new Thread(new ThreadStart(Producer)).Start();
            new Thread(new ThreadStart(Customer)).Start();
            Console.Read();
        }

        private static void Producer()
        {
            uint ppointer=0;
            int temp;
            while (true)
            {      
                //!!!!Attention!!!!!NEVER MIX Orders
                //如果empty与mutex的顺序反了,就会发生死锁!
                empty.WaitOne();
                mutex.WaitOne();
                temp = rand.Next(1, 100);
                buffer[ppointer] = temp;
                Console.WriteLine("Producer works at {0} with {1}",ppointer,temp);
                ppointer = (ppointer + 1)%10;
                mutex.ReleaseMutex();
                full.Release();
                Thread.Sleep(400);
            }
        }


        private static void Customer()
        {
            uint cpointer=0;
            int temp;
            while (true)
            {
                full.WaitOne();
                mutex.WaitOne();
                temp = rand.Next(1, 100);
                 temp = buffer[cpointer];
                Console.WriteLine("Customer gains at {0} with {1}", cpointer, temp);
                cpointer = (cpointer + 1) % 10;
                mutex.ReleaseMutex();
                empty.Release();
                Thread.Sleep(400);
            }
        }
    }

}


3.问题变形:桌上有一个空盘子,只允许放一个水果。爸爸可以放苹果。也可以放橘子。儿子要吃苹果,女儿要吃橘子。试实现之。


using System;
using System.Threading;

namespace OS
{
    internal class Program
    {
        private static Mutex mutex = new Mutex();
        private static Semaphore Sempty = new Semaphore(1, 1);
        private static Semaphore Sorange = new Semaphore(0, 1);
        private static Semaphore Sapple = new Semaphore(0, 1);
        private static Fruit buffer = 0;
        private static Random rand = new Random();

        public enum Fruit
        {
            Empty,
            Apple,
            Orange
        };

        private static void Main(string[] args)
        {
            new Thread(new ThreadStart(Papa)).Start();
            new Thread(new ThreadStart(Son)).Start();
            new Thread(new ThreadStart(Daughter)).Start();
            Console.Read();
        }

        private static void Papa()
        {
            while (true)
            {
                int temp = 0;
                Sempty.WaitOne();
                mutex.WaitOne();
                temp = rand.Next(1,3);
                if (temp == 1)
                {
                    Console.WriteLine("Papa put an apple");
                    buffer = Fruit.Apple;
                    mutex.ReleaseMutex();
                    Sapple.Release();
                }
                else
                {
                    Console.WriteLine("Papa put an Orange");
                    buffer = Fruit.Orange;
                    mutex.ReleaseMutex();
                    Sorange.Release();
                }
                Thread.Sleep(400);
            }
        }

        private static void Son()
        {
            while (true)
            {
                Sapple.WaitOne();
                mutex.WaitOne();
                Console.WriteLine("Son  eat an {0}", buffer);
                mutex.ReleaseMutex();
                Sempty.Release();
                Thread.Sleep(400);
            }
        }

        private static void Daughter()
        {
            while (true)
            {
                Sorange.WaitOne();
                mutex.WaitOne();
                Console.WriteLine("Daughter  eat an {0}", buffer);
                mutex.ReleaseMutex();
                Sempty.Release();
                Thread.Sleep(400);
            }
        }
    }
}



二、哲学家用餐问题

个哲学家围着桌子共同进餐,每个哲学家两侧各有一支筷子。试设计同步算法,使哲学家都能吃上饭。

using System;
using System.Threading;

namespace PhilosophersProblem
{
    class Program
    {
        static Semaphore[] chopsticks = { new Semaphore(1, 1)
                                            , new Semaphore(1, 1)
                                            , new Semaphore(1, 1)
                                            , new Semaphore(1, 1),
                                            new Semaphore(1, 1), };
       
        static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++)
            {
                new Thread(new ParameterizedThreadStart(philosopher)).Start(i);
            }
            Console.Read();
        }

        private static void philosopher(object input)
        {
            int i = (int)input;
            chopsticks[i].WaitOne();
            chopsticks[(i + 1)%5].WaitOne();

            Console.WriteLine("Philosopher{0}: I am eating",i);
            Thread.Sleep(1000);

            chopsticks[i].Release();
            chopsticks[(i + 1)%5].Release();
        }
    }
}

三、读者写者问题

一个文件,允许多个读者同时读取,只能允许一个写者同时写,写者写的时候不能读。试实现之。 

using System;
using System.Threading;

namespace ReaderWriter
{
    class ReaderWriter
    {

        //Warning : Some Error will occur if more than one Reader is newed
        //Using Semaphore can solve this however here I take mutex as example to show the concept. 
         static  int Readcount =0 ;
         static  Mutex WMutex = new Mutex();
         static Mutex RMutex = new Mutex();
         static int buffer = 0;
         static Random rand = new Random();

        static void Main(string[] args)
        {
            new Thread(new ThreadStart(Writer)).Start();
            new Thread(new ThreadStart(Reader)).Start();
            new Thread(new ThreadStart(Reader)).Start();


            Console.Read();
        }

        private static void Reader()
        {
            while (true)
            {
                RMutex.WaitOne();
                if (Readcount == 0)
                {
                    WMutex.WaitOne();
                }
                Readcount++;
                RMutex.ReleaseMutex();

                Console.WriteLine("I have read this:{0}", buffer.ToString());

                RMutex.WaitOne();
                Readcount--;
                if (Readcount == 0)
                {
                    WMutex.ReleaseMutex();
                }
                RMutex.ReleaseMutex();
                Thread.Sleep(300);
            }
        }

        private static void Writer()
        {
            while (true)
            {
                WMutex.WaitOne();
                buffer = rand.Next(1, 10);
                Console.WriteLine("Write {0}",buffer);
                WMutex.ReleaseMutex();
                Thread.Sleep(1000);
            }
        }
    }
}

就是这样...













你可能感兴趣的:(操作系统,C#,算法)