zoukankan      html  css  js  c++  java
  • C# Semaphore

    1.Semaphore定义
    Semaphore,是负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。也是操作系统中用于控制进程同步互斥的量。

    Semaphore常用的方法有两个WaitOne()和Release(),Release()的作用是退出信号量并返回前一个计数,而WaitOne()则是阻止当前线程,直到当前线程的WaitHandle 收到信号。这里我举一个例子让大家更容易理解:

    当我们这样实例化Semaphore时候,如果写Semaphore sema = new Semaphore(x,y)这种表达式,就可以理解为这样一个场景

    有一队人排队上洗手间,人就相当于线程,x为还剩余的位置数量,y为总的位置数量。

    WaitOne()方法就相当于人在等待洗手间位置的行为,而Release()方法就相当于一个人从洗手间出来的行为,这里再假设x和y都为5,说明开始的时候洗手间有5个空位置,且总共只有5个位置,当一队超过5个人的队伍要上洗手间的就排队,首先WaitOne()方法等待,发现有空位就依次进去,每进去一个空位减一,直到进去5之后个没有空位,这时候后面的人就一直等待,直到进去的人从洗手间出来Release()方法,空位加一,在等待WaitOne()方法的人发现有空位又进去一个空位减一……如此循环往复。

    2、代码举例

     1 class Program
     2     {
     3         static Semaphore semaphore;
     4         //当前信号量中线程数量
     5         static int count;
     6         //用于生成随机数
     7         static Random r;
     8 
     9         static void Main()
    10         {
    11             r = new Random();
    12             //初始化信号量:初始请求数为1,最大请求数为3
    13             semaphore = new Semaphore(1, 3);
    14             //放出10个线程
    15             for (int i = 0; i < 5; i++)
    16                 ThreadPool.QueueUserWorkItem(doo, i + 1);
    17             Console.ReadKey(true);
    18         }
    19 
    20         static void doo(object arg)
    21         {
    22             int id = (int)arg;
    23             PrintStatus(id, "等待信号量");
    24             //获取一个资源
    25             semaphore.WaitOne();
    26             PrintStatus(id, "获得信号量开始执行");
    27             PrintCount(1);
    28             Thread.Sleep(r.Next(1000));
    29             PrintStatus(id, "退出");
    30             PrintCount(-1);
    31             //释放一个资源
    32             semaphore.Release();
    33 
    34         }
    35 
    36         //输出线程状态
    37         static void PrintStatus(int id, string s)
    38         {
    39             Console.WriteLine("线程{0}:{1}", id, s);
    40         }
    41 
    42         //修改并输出线程数量
    43         static void PrintCount(int add)
    44         {
    45             //在多进程(线程)的操作系统中不能被其它进程(线程)打断的操作就叫原子操作,一个线程在执行其它线程无法抢占。
    46             //对两个 32 位整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。
    47             Interlocked.Add(ref count, add);
    48             //以原子操作的形式,将 32 位有符号整数设置为指定的值并返回原始值。
    49             Console.WriteLine("=> 信号量值:{0}", Interlocked.Exchange(ref count, count));
    50         }
    51     }

    参考以下内容:https://www.cnblogs.com/legion/p/6934363.html

    https://blog.csdn.net/yangwohenmai1/article/details/90236036

  • 相关阅读:
    【BZOJ 4151 The Cave】
    【POJ 3080 Blue Jeans】
    【ZBH选讲·树变环】
    【ZBH选讲·拍照】
    【ZBH选讲·模数和】
    【CF Edu 28 C. Four Segments】
    【CF Edu 28 A. Curriculum Vitae】
    【CF Edu 28 B. Math Show】
    【CF Round 439 E. The Untended Antiquity】
    【CF Round 439 C. The Intriguing Obsession】
  • 原文地址:https://www.cnblogs.com/mojiejushi/p/13221630.html
Copyright © 2011-2022 走看看