コード例 #1
0
ファイル: Program.cs プロジェクト: dudesuh/s1617i-li51d
        // use semaphore in a producer/consumer context using asynchronous APM acquires
        private static bool TestSemaphoreInAApmProducerConsumerContext()
        {
            const int RUN_TIME            = 30 * 1000;
            const int EXIT_TIME           = 50;
            const int PRODUCER_THREADS    = 10;
            const int CONSUMER_THREADS    = 20;
            const int QUEUE_SIZE          = PRODUCER_THREADS * 4;
            const int MIN_TIMEOUT         = 0;
            const int MAX_TIMEOUT         = 50;
            const int MIN_CANCEL_INTERVAL = 50;
            const int MAX_CANCEL_INTERVAL = 100;
            const int MIN_PAUSE_INTERVAL  = 10;
            const int MAX_PAUSE_INTERVAL  = 100;
            const int PRODUCTION_ALIVE    = 100;
            const int CONSUMER_ALIVE      = 100;

            Thread[] pthrs                   = new Thread[PRODUCER_THREADS];
            Thread[] cthrs                   = new Thread[CONSUMER_THREADS];
            int[]    productions             = new int[PRODUCER_THREADS];
            int[]    productionCancellations = new int[PRODUCER_THREADS];
            int[]    consumptions            = new int[CONSUMER_THREADS];
            int[]    consumptionTimeouts     = new int[CONSUMER_THREADS];
            bool     exit = false;
            BlockingQueue_ <String> queue = new BlockingQueue_ <String>(QUEUE_SIZE);

            // Create and start consumer threads.

            for (int i = 0; i < CONSUMER_THREADS; i++)
            {
                int ctid = i;
                cthrs[i] = new Thread(() => {
                    Random rnd = new Random(ctid);
                    do
                    {
                        var ar = queue.BeginTake(rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT), CancellationToken.None,
                                                 null, null);
                        try
                        {
                            while (!ar.IsCompleted)
                            {
                                Thread.Sleep(10);
                            }
                        }
                        catch (ThreadInterruptedException)
                        {
                            break;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("***Exception: {0}: {1}", ex.GetType(), ex.Message);
                            break;
                        }
                        finally
                        {
                            if (ar.IsCompleted)
                            {
                                if (queue.EndTake(ar) != null)
                                {
                                    consumptions[ctid]++;
                                }
                                else
                                {
                                    consumptionTimeouts[ctid]++;
                                }
                            }
                        }
                        int sleepTime = 0;
                        if (consumptions[ctid] % CONSUMER_ALIVE == 0)
                        {
                            Console.Write("[#c{0}]", ctid);
                            sleepTime = rnd.Next(MIN_PAUSE_INTERVAL, MAX_PAUSE_INTERVAL);
                        }
                        try
                        {
                            Thread.Sleep(sleepTime);
                        }
                        catch (ThreadInterruptedException)
                        {
                            break;
                        }
                    } while (!Volatile.Read(ref exit));
                });
                cthrs[i].Priority = ThreadPriority.Highest;
                cthrs[i].Start();
            }

            // Create and start producer threads.
            for (int i = 0; i < PRODUCER_THREADS; i++)
            {
                int ptid = i;
                pthrs[i] = new Thread(() => {
                    Random rnd = new Random(ptid);
                    CancellationTokenSource cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL));
                    do
                    {
                        using (var done = new ManualResetEventSlim(false))
                        {
                            queue.BeginPut(rnd.Next().ToString(), Timeout.Infinite, cts.Token, (ar) => {
                                try
                                {
                                    queue.EndPut(ar);
                                    productions[ptid]++;
                                }
                                catch (OperationCanceledException)
                                {
                                    productionCancellations[ptid]++;
                                    cts.Dispose();
                                    cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL));
                                }
                                finally
                                {
                                    done.Set();
                                }
                            }, null);
                            try
                            {
                                done.Wait();
                            }
                            catch (ThreadInterruptedException)
                            {
                                break;
                            }
                        }

                        int sleepTime = 0;
                        if (consumptions[ptid] % PRODUCTION_ALIVE == 0)
                        {
                            Console.Write("[#p{0}]", ptid);
                            sleepTime = rnd.Next(MIN_PAUSE_INTERVAL, MAX_PAUSE_INTERVAL);
                        }
                        try
                        {
                            Thread.Sleep(sleepTime);
                        }
                        catch (ThreadInterruptedException)
                        {
                            break;
                        }
                    } while (!Volatile.Read(ref exit));
                });
                pthrs[i].Start();
            }

            // run the test for a while
            int endTime = Environment.TickCount + RUN_TIME;

            do
            {
                Thread.Sleep(50);
                if (Console.KeyAvailable)
                {
                    Console.Read();
                    break;
                }
            } while (Environment.TickCount < endTime);

            Volatile.Write(ref exit, true);
            Thread.Sleep(EXIT_TIME);

            // Wait until all producer have been terminated.
            int sumProductions = 0;

            for (int i = 0; i < PRODUCER_THREADS; i++)
            {
                if (pthrs[i].IsAlive)
                {
                    pthrs[i].Interrupt();
                }
                pthrs[i].Join();
                sumProductions += productions[i];
            }

            int sumConsumptions = 0;

            // Wait until all consumer have been terminated.
            for (int i = 0; i < CONSUMER_THREADS; i++)
            {
                if (cthrs[i].IsAlive)
                {
                    cthrs[i].Interrupt();
                }
                cthrs[i].Join();
                sumConsumptions += consumptions[i];
            }

            // Display consumer results
            Console.WriteLine("\nConsumer counters:");
            for (int i = 0; i < CONSUMER_THREADS; i++)
            {
                if (i != 0 && i % 4 == 0)
                {
                    Console.WriteLine();
                }
                else if (i != 0)
                {
                    Console.Write(' ');
                }
                Console.Write("[#c{0:D2}: {1,4}/{2, 3}]", i, consumptions[i], consumptionTimeouts[i]);
            }

            // consider not consumed productions
            sumConsumptions += queue.Count;

            Console.WriteLine("\nProducer counters:");
            for (int i = 0; i < PRODUCER_THREADS; i++)
            {
                if (i != 0 && i % 4 == 0)
                {
                    Console.WriteLine();
                }
                else if (i != 0)
                {
                    Console.Write(' ');
                }
                Console.Write("[#p{0:D2}: {1,4}/{2, 3}]", i, productions[i], productionCancellations[i]);
            }
            Console.WriteLine("\n--productions: {0}, consumptions: {1}", sumProductions, sumConsumptions);
            return(sumConsumptions == sumProductions);
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: dudesuh/s1617i-li51d
        // use semaphore in a producer/consumer context using asynchronous TAP acquires
        private static bool TestSemaphoreInATapProducerConsumerContext()
        {
            const int RUN_TIME           = 30 * 1000;
            const int EXIT_TIME          = 50;
            const int PRODUCER_THREADS   = 10;
            const int CONSUMER_THREADS   = 20;
            const int QUEUE_SIZE         = PRODUCER_THREADS * 4;
            const int MIN_PAUSE_INTERVAL = 10;
            const int MAX_PAUSE_INTERVAL = 100;
            const int PRODUCTION_ALIVE   = 100;
            const int CONSUMER_ALIVE     = 100;

            Thread[] pthrs                = new Thread[PRODUCER_THREADS];
            Thread[] cthrs                = new Thread[CONSUMER_THREADS];
            int[]    productions          = new int[PRODUCER_THREADS];
            int[]    consumptions         = new int[CONSUMER_THREADS];
            bool     exit                 = false;
            BlockingQueue_ <String> queue = new BlockingQueue_ <String>(QUEUE_SIZE);

            // Create and start consumer threads.

            for (int i = 0; i < CONSUMER_THREADS; i++)
            {
                int ctid = i;
                cthrs[i] = new Thread(() => {
                    Random rnd = new Random(ctid);
                    do
                    {
                        try
                        {
                            var item = queue.TakeAsync().Result;
                            consumptions[ctid]++;
                        }
                        catch (ThreadInterruptedException)
                        {
                            break;
                        }
                        int sleepTime = 0;
                        if (consumptions[ctid] % CONSUMER_ALIVE == 0)
                        {
                            Console.Write("[#c{0}]", ctid);
                            sleepTime = rnd.Next(MIN_PAUSE_INTERVAL, MAX_PAUSE_INTERVAL);
                        }
                        try
                        {
                            Thread.Sleep(sleepTime);
                        }
                        catch (ThreadInterruptedException)
                        {
                            break;
                        }
                    } while (!Volatile.Read(ref exit));
                });
                cthrs[i].Priority = ThreadPriority.Highest;
                cthrs[i].Start();
            }

            // Create and start producer threads.
            for (int i = 0; i < PRODUCER_THREADS; i++)
            {
                int ptid = i;
                pthrs[i] = new Thread(() => {
                    Random rnd = new Random(ptid);
                    do
                    {
                        try
                        {
                            queue.PutAsync(rnd.Next().ToString()).Wait();
                            productions[ptid]++;
                        }
                        catch (ThreadInterruptedException)
                        {
                            break;
                        }
                        int sleepTime = 0;
                        if (consumptions[ptid] % PRODUCTION_ALIVE == 0)
                        {
                            Console.Write("[#p{0}]", ptid);
                            sleepTime = rnd.Next(MIN_PAUSE_INTERVAL, MAX_PAUSE_INTERVAL);
                        }
                        try
                        {
                            Thread.Sleep(sleepTime);
                        }
                        catch (ThreadInterruptedException)
                        {
                            break;
                        }
                    } while (!Volatile.Read(ref exit));
                });
                pthrs[i].Start();
            }

            // run the test for a while
            int endTime = Environment.TickCount + RUN_TIME;

            do
            {
                Thread.Sleep(50);
                if (Console.KeyAvailable)
                {
                    Console.Read();
                    break;
                }
            } while (Environment.TickCount < endTime);

            Volatile.Write(ref exit, true);
            Thread.Sleep(EXIT_TIME);

            // Wait until all producer have been terminated.
            int sumProductions = 0;

            for (int i = 0; i < PRODUCER_THREADS; i++)
            {
                if (pthrs[i].IsAlive)
                {
                    pthrs[i].Interrupt();
                }
                pthrs[i].Join();
                sumProductions += productions[i];
            }

            int sumConsumptions = 0;

            // Wait until all consumer have been terminated.
            for (int i = 0; i < CONSUMER_THREADS; i++)
            {
                if (cthrs[i].IsAlive)
                {
                    cthrs[i].Interrupt();
                }
                cthrs[i].Join();
                sumConsumptions += consumptions[i];
            }

            // Display consumer results
            Console.WriteLine("\nConsumer counters:");
            for (int i = 0; i < CONSUMER_THREADS; i++)
            {
                if (i != 0 && i % 4 == 0)
                {
                    Console.WriteLine();
                }
                else if (i != 0)
                {
                    Console.Write(' ');
                }
                Console.Write("[#c{0:D2}: {1,4}]", i, consumptions[i]);
            }

            // consider not consumed productions
            sumConsumptions += queue.Count;

            Console.WriteLine("\nProducer counters:");
            for (int i = 0; i < PRODUCER_THREADS; i++)
            {
                if (i != 0 && i % 4 == 0)
                {
                    Console.WriteLine();
                }
                else if (i != 0)
                {
                    Console.Write(' ');
                }
                Console.Write("[#p{0:D2}: {1,4}]", i, productions[i]);
            }
            Console.WriteLine("\n--productions: {0}, consumptions: {1}", sumProductions, sumConsumptions);
            return(sumConsumptions == sumProductions);
        }