美文网首页
C# Semaphore 简单理解

C# Semaphore 简单理解

作者: 大其心宏其量扩其识 | 来源:发表于2021-01-17 13:16 被阅读0次

    Semaphore [ /ˈseməfɔːr/ ]

    信号量:主要作为进程之间以及同一进程的不同线程之间的同步和互斥手段。
    可以把多线程比作马路,Semaphore比作红绿灯
    比如马路有10车道,initialCount表示初次可通行数量,maximumCount最大可通行数量,比如设置为4,一次最多放4条,


    semophore.png

    主要方法

    WaitOne()阻塞线程,等灯来
    Release(N) 同时放行条数,最大不能超过maximumCount
    Close()释放所有

    使用方式1

    有10个线程,同时只执行3条线程,每完成一个就Release一个,等待中的就补上去

    using System;
    using System.Threading;
    
    namespace TestThread
    {
        class Program
        {
            // A semaphore that simulates a limited resource pool.
            //
            private static Semaphore _pool;
    
            // A padding interval to make the output more orderly.
            //private static int _padding;
    
            public static void Main()
            {
                // Create a semaphore that can satisfy up to three
                // concurrent requests. Use an initial count of zero,
                // so that the entire semaphore count is initially
                // owned by the main program thread.
                //
                _pool = new Semaphore(3, 3);
    
                // Create and start five numbered threads. 
                //
                for (int i = 1; i <= 10; i++)
                {
                    Thread t = new Thread(new ParameterizedThreadStart(Worker));
                    t.Name = "线程" + i;
                    // Start the thread, passing the number.
                    //
                    t.Start(i);
                }
    
                Console.WriteLine("Main thread exits.");
            }
    
            private static void Worker(object num)
            {
                // Each worker thread begins by requesting the
                // semaphore.
                Console.WriteLine(Thread.CurrentThread.Name + "等待中...");
                _pool.WaitOne();
    
                // A padding interval to make the output more orderly.
                //int padding = Interlocked.Add(ref _padding, 100);
    
                Console.WriteLine(Thread.CurrentThread.Name + ">>>>>>>>>>>>>>>>>>开始执行..." + Environment.TickCount64);
    
                // The thread's "work" consists of sleeping for 
                // about a second. Each thread "works" a little 
                // longer, just to make the output more orderly.
                //
                Thread.Sleep(1000 + (int)num * 100);
    
                Console.WriteLine(Thread.CurrentThread.Name + "<<<<<<<<<<<<<<<<<退出" + Environment.TickCount64);
                ;
                Console.WriteLine("Semaphore.Release---------------------" + _pool.Release());
            }
        }
    }
    
    
    线程9等待中...
    Main thread exits.
    线程1等待中...
    线程2等待中...
    线程3等待中...
    线程4等待中...
    线程5等待中...
    线程6等待中...
    线程7等待中...
    线程8等待中...
    线程10等待中...
    线程9>>>>>>>>>>>>>>>>>>开始执行...1268589031
    线程1>>>>>>>>>>>>>>>>>>开始执行...1268589031
    线程2>>>>>>>>>>>>>>>>>>开始执行...1268589031
    线程1<<<<<<<<<<<<<<<<<退出1268590140
    Semaphore.Release---------------------0
    线程3>>>>>>>>>>>>>>>>>>开始执行...1268590140
    线程2<<<<<<<<<<<<<<<<<退出1268590234
    Semaphore.Release---------------------0
    线程4>>>>>>>>>>>>>>>>>>开始执行...1268590234
    线程9<<<<<<<<<<<<<<<<<退出1268590937
    Semaphore.Release---------------------0
    线程5>>>>>>>>>>>>>>>>>>开始执行...1268590937
    线程3<<<<<<<<<<<<<<<<<退出1268591437
    Semaphore.Release---------------------0
    线程6>>>>>>>>>>>>>>>>>>开始执行...1268591437
    线程4<<<<<<<<<<<<<<<<<退出1268591640
    Semaphore.Release---------------------0
    线程7>>>>>>>>>>>>>>>>>>开始执行...1268591640
    线程5<<<<<<<<<<<<<<<<<退出1268592437
    Semaphore.Release---------------------0
    线程8>>>>>>>>>>>>>>>>>>开始执行...1268592437
    线程6<<<<<<<<<<<<<<<<<退出1268593031
    Semaphore.Release---------------------0
    线程10>>>>>>>>>>>>>>>>>>开始执行...1268593031
    线程7<<<<<<<<<<<<<<<<<退出1268593343
    Semaphore.Release---------------------0
    线程8<<<<<<<<<<<<<<<<<退出1268594234
    Semaphore.Release---------------------1
    线程10<<<<<<<<<<<<<<<<<退出1268595046
    Semaphore.Release---------------------2
    

    使用方式2

    using System;
    using System.Collections.Generic;
    using System.Threading;
    
    namespace TestThread
    {
        class Program2
        {
            private static Semaphore _semaphore;
    
            private static Queue<int> m_TaskQueue = new Queue<int>();
    
            public static void Main()
            {
                //
                _semaphore = new Semaphore(0, int.MaxValue);
    
                ThreadPool.QueueUserWorkItem(Run);
                ThreadPool.QueueUserWorkItem(QueueTask);
    
                Thread.Sleep(11000);
                Console.WriteLine("Main thread exits.");
            }
    
            private static void QueueTask(object state)
            {
                for (int i = 0; i < 10; i++)
                {
                    lock (m_TaskQueue)
                    {
                        m_TaskQueue.Enqueue(i);
                        _semaphore.Release();
                    }
    
                    Thread.Sleep(1000);
                }
            }
    
            private static void Run(object state)
            {
                while (true)
                {
                    Console.WriteLine("开始等待");
                    _semaphore.WaitOne();
                    int task = 0;
                    lock (m_TaskQueue)
                    {
                        if (m_TaskQueue.Count == 0)
                        {
                            _semaphore.Dispose();
                            Console.WriteLine("队列执行结束");
                            return;
                        }
                        task = m_TaskQueue.Dequeue();
                    }
                    
                    Console.WriteLine("执行任务" + task);
                }
            }
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:C# Semaphore 简单理解

          本文链接:https://www.haomeiwen.com/subject/fdeaaktx.html