C# Semaphore 简单理解

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

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


C# Semaphore 简单理解_第1张图片
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 m_TaskQueue = new Queue();

        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 简单理解)