Esempio n. 1
0
 // Put an item in the queue synchronously enabling timeout and cancellation
 public bool Put(T item, int timeout      = Timeout.Infinite,
                 CancellationToken cToken = default(CancellationToken))
 {
     if (freeSlots.Acquire(timeout: timeout, token: cToken))
     {
         lock (room)
             room[putIdx++ % capacity] = item;
         filledSlots.Release();
         return(true);
     }
     else
     {
         return(false);
     }
 }
Esempio n. 2
0
        // test semaphore as a mutual exclusion lock using synchronous acquires
        private static bool TestSemaphoreAsLockSync()
        {
            const int SETUP_TIME          = 50;
            const int RUN_TIME            = 30 * 1000;
            int       THREADS             = 50;
            const int MIN_TIMEOUT         = 1;
            const int MAX_TIMEOUT         = 50;
            const int MIN_CANCEL_INTERVAL = 1;
            const int MAX_CANCEL_INTERVAL = 50;

            Thread[] tthrs            = new Thread[THREADS];
            int[]    privateCounters  = new int[THREADS];
            int[]    timeouts         = new int[THREADS];
            int[]    cancellations    = new int[THREADS];
            int      issuedInterrupts = 0;

            int[] sensedInterrupts     = new int[THREADS];
            int   sharedCounter        = 0;
            bool  exit                 = false;
            ManualResetEventSlim start = new ManualResetEventSlim();
            SemaphoreSlim1       _lock = new SemaphoreSlim1(1, 1);

            /**
             * Create and start acquirer/releaser threads
             */

            for (int i = 0; i < THREADS; i++)
            {
                int tid = i;
                tthrs[i] = new Thread(() => {
                    Random rnd = new Random(Thread.CurrentThread.ManagedThreadId);
                    start.Wait();
                    CancellationTokenSource cts =
                        new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL));
                    do
                    {
                        do
                        {
                            try {
                                if (_lock.Acquire(timeout: rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT), token: cts.Token))
                                {
                                    break;
                                }
                                timeouts[tid]++;
                            }
                            catch (OperationCanceledException) {
                                cancellations[tid]++;
                                cts.Dispose();
                                cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL));
                            }
                            catch (ThreadInterruptedException) {
                                sensedInterrupts[tid]++;
                            }
                        } while (true);
                        try {
                            Thread.Sleep(0);
                        }
                        catch (ThreadInterruptedException) {
                            sensedInterrupts[tid]++;
                        }
                        sharedCounter++;

                        if (THREADS > 1)
                        {
                            if (rnd.Next(100) < 99)
                            {
                                Thread.Yield();
                            }
                            else
                            {
                                try {
                                    Thread.Sleep(rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT));
                                }
                                catch (ThreadInterruptedException) {
                                    sensedInterrupts[tid]++;
                                }
                            }
                        }

                        // release the lock
                        _lock.Release();
                        privateCounters[tid]++;
                        if (THREADS > 1)
                        {
                            try {
                                if ((privateCounters[tid] % 100) == 0)
                                {
                                    Console.Write("[#{0:D2}]", tid);
                                }
                            }
                            catch (ThreadInterruptedException) {
                                sensedInterrupts[tid]++;
                            }
                        }
                    } while (!Volatile.Read(ref exit));
                    try {
                        Thread.Sleep(10);
                    }
                    catch (ThreadInterruptedException) {
                        sensedInterrupts[tid]++;
                    }
                });
                tthrs[i].Start();
            }
            Thread.Sleep(SETUP_TIME);
            Stopwatch sw = Stopwatch.StartNew();

            start.Set();
            Random grnd    = new Random(Thread.CurrentThread.ManagedThreadId);
            int    endTime = Environment.TickCount + RUN_TIME;

            //...
            do
            {
                Thread.Sleep(grnd.Next(5));

#if SEND_INTERRUPTS
                if (THREADS > 1)
                {
                    tthrs[grnd.Next(THREADS)].Interrupt();
                    issuedInterrupts++;
                }
#endif

                if (Console.KeyAvailable)
                {
                    Console.Read();
                    break;
                }
#if RUN_CONTINOUSLY
            } while (true);
#else
            } while (Environment.TickCount < endTime);