private bool TryEating(Philosopher philosopher)
        {
            if (Monitor.TryEnter(table.forks))
            {
                if (philosopher.left.isFree && philosopher.right.isFree)
                {
                    lock (philosopher.left)
                    {
                        lock (philosopher.right)
                        {
                            philosopher.TakeForks();
                            Monitor.Exit(table.forks);
                            philosopher.Eat();
                            return(true);
                        }
                    }
                }
                else
                {
                    Monitor.Exit(table.forks);
                }
            }

            return(false);
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            Stopwatch watch = new Stopwatch();
            int       n, thinkingTime, eatingTime;
            int       waitedForFork = 0;
            string    consoleInput;

            Console.Write("Enter number of philosophers: ");
            consoleInput = Console.ReadLine();
            n            = int.Parse(consoleInput);

            Console.Write("Enter max thinking time in ms: ");
            consoleInput = Console.ReadLine();
            thinkingTime = int.Parse(consoleInput);

            Console.Write("Enter max eating time in ms: ");
            consoleInput = Console.ReadLine();
            eatingTime   = int.Parse(consoleInput);

            Console.WriteLine();

            watch.Start();
            CancellationTokenSource source = new CancellationTokenSource();

            forks = new object[n];
            Task[] pTasks = new Task[n];

            #region Deadlock
            //for (int i = 0; i < n; i++)
            //{
            //    forks[i] = new object();
            //}

            //pTasks[0] = new Task(() =>
            //{
            //    Philosopher p = new Philosopher();
            //    p.Eat(forks[n - 1], forks[0],
            //        n - 1, 0, 0, thinkingTime, eatingTime, source.Token);
            //});
            //pTasks[0].Start();

            //for (int i = 1; i < n; i++)
            //{
            //    int ix = i;
            //    pTasks[i] = new Task(() =>
            //    {
            //        Philosopher p = new Philosopher();
            //        p.Eat(forks[ix - 1], forks[ix],
            //            ix - 1, ix, ix, thinkingTime, eatingTime, source.Token);
            //    });
            //    pTasks[i].Start();
            //}
            #endregion

            #region NoCircularWait
            for (int i = 0; i < n; i++)
            {
                forks[i] = new object();
            }

            pTasks[0] = new Task(() =>
            {
                Philosopher p = new Philosopher();
                p.Eat(forks[0], forks[n - 1],
                      n - 1, 0, 0, thinkingTime, eatingTime, source.Token);

                Interlocked.Add(ref waitedForFork, (int)p.WaitForFork);
            });
            pTasks[0].Start();

            for (int i = 1; i < n; i++)
            {
                int ix = i;
                pTasks[i] = new Task(() =>
                {
                    Philosopher p = new Philosopher();

                    if (n % 2 == 1)
                    {
                        p.Eat(forks[ix - 1], forks[ix],
                              ix - 1, ix, ix, thinkingTime, eatingTime, source.Token);
                    }
                    else
                    {
                        p.Eat(forks[ix], forks[ix - 1],
                              ix - 1, ix, ix, thinkingTime, eatingTime, source.Token);
                    }

                    Interlocked.Add(ref waitedForFork, (int)p.WaitForFork);
                });
                pTasks[i].Start();
            }
            #endregion

            // Let them eat
            Thread.Sleep(1000);

            // Stop eating
            source.Cancel();

            // Wait till all finished
            Task.WaitAll(pTasks);

            watch.Stop();

            Console.WriteLine($"\n{watch.ElapsedMilliseconds}ms waittime\n{waitedForFork}ms sum waited for fork\nPress any key to exit.");
            Console.ReadLine();
        }