Bakery Algorithm的c#实现用于多线程互斥访问临界资源

来源:互联网 发布:知乎 电脑下载 编辑:程序博客网 时间:2024/06/05 10:29

算法原理:每个线程进入的时候都要取得一个编号,对于不同线程编号较小的较先运行,编号相同时进程号小的先运行。

using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace Bakery{    class Program    {        public static int[] data = new int[100000];        public static int total = 10;        private static object ojb = new object();        static int num = 10;        static int threads=4;         static List<int> ticket = new List<int>(threads); // 保留票号          static List<bool> entering = new List<bool>(threads); //记录线程是否要进入        public static void addLock(int pid) // thread ID        {            //Console.WriteLine(pid);            entering[pid] = true;            int max = 0;            for (int i = 0; i < threads; ++i)           {                int current = ticket[i];                if (current > max)                {                  max = current;                }            }             ticket[pid]=max+1;              entering[pid]=false;        for (int i = 0; i < ticket.Count; ++i)        {             if (i != pid)            {                 while (entering[i] == true) { ; } // wait while other thread picks a ticket                while (ticket[i] != 0 && ( ticket[pid] > ticket[i]  ||                     (ticket[pid] == ticket[i] && pid > i)))                        { ; }            }        }     // The critical section goes here... }        public static void unlock(int pid)     {        ticket[pid] = 0;     }        public static void changeValue(object pid)        {            int p = Convert.ToInt32(pid.ToString());            addLock(p);                for (int i = 0; i < total; i++)                {                    num = num + 1;                    Console.WriteLine(num);                }                unlock(p);        }        public static void readValue(object pid)        {            int p = Convert.ToInt32(pid.ToString());            addLock(p);                for (int i = 0; i < total; i++)                {                    num = num - 1;                    Console.WriteLine(num);                }                unlock(p);        }        static void Main(string[] args)        {            ticket = new List<int>(threads);            entering = new List<bool>(threads);            for (int i = 0; i < threads;i++ )            {                ticket.Add(-1);                entering.Add(false);            }                for (int i = 0; i < total; i++)                {                    data[i] = 0;                }            Stopwatch stopwatch = new Stopwatch();            stopwatch.Start();            int num = 10;            Thread[] t = new Thread[num];            t[0] = new Thread(new ParameterizedThreadStart(changeValue));            t[1] = new Thread(new ParameterizedThreadStart(readValue));            t[2] = new Thread(new ParameterizedThreadStart(readValue));            t[3] = new Thread(new ParameterizedThreadStart(changeValue));            stopwatch.Start();            t[0].Start(0);            t[1].Start(1);            t[2].Start(2);            t[3].Start(3);            t[0].Join();            t[1].Join();            t[2].Join();            t[3].Join();            stopwatch.Stop();            Console.WriteLine("运行时间" + stopwatch.ElapsedMilliseconds.ToString());            Console.ReadKey();        }    }}


0 0
原创粉丝点击