信号量(Semaphore)是一种CLR中的内核同步对象。与标准的排他锁对象(Monitor,Mutex,SpinLock)不同的是,它不是一个排他的锁对象,它与SemaphoreSlim,ReaderWriteLock等一样允许多个有限的线程同时访问共享内存资源。Semaphore就好像一个栅栏,有一定的容量,当里面的线程数量到达设置的最大值时候,就没有线程可以进去。然后,如果一个线程工作完成以后出来了,那下一个线程就可以进去了。Semaphore的WaitOne或Release等操作分别将自动地递减或者递增信号量的当前计数值。当线程试图对计数值已经为0的信号量执行WaitOne操作时,线程将阻塞直到计数值大于0。

  Semaphore是表示一个Windows内核的信号量对象(操作系统级别,可以跨进程或AppDomain)。如果预计等待的时间较短,使用SemaphoreSlim(单进程)带来的开销更小。关于两者的区别如下:

  System.Threading.Semaphore 类表示一个命名(系统范围内)或本地信号量。它是环绕 Win32 信号量对象的精简包装器。Win32 信号量是计数信号量,该可用于控制对资源池的访问。

  SemaphoreSlim 类表示一个轻量、快速的信号量,可在等待时间预计很短的情况下用于在单个进程内等待。 SemaphoreSlim 尽可能多地依赖公共语言运行时 (CLR) 提供的同步基元。但是,它还提供延迟初始化、基于内核的等待句柄,作为在多个信号量上进行等待的必要支持。 SemaphoreSlim 也支持使用取消标记,但不支持命名信号量或使用用于同步的等待句柄。

Semaphore的WaitOne或者Release方法的调用大约会耗费1微秒的系统时间,而优化后的SemaphoreSlim则需要大致四分之一微秒。在计算中大量频繁使用它的时候SemaphoreSlim还是优势明显,所以在4.0以后的多线程开发中,推荐使用SemaphoreSlim。

在构造Semaphore时,最少需要2个参数。信号量的初始容量和最大的容量。

  1. [SecuritySafeCritical]
  2. [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  3. public Semaphore(int initialCount, int maximumCount);

Semaphore

initialCount:信号量可以接受的并发请求数量的初始容量

maximumCount:信号量可以接受的并发请求数量的最大容量

示例代码:

  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4.  
  5. public class Example
  6. {
  7. private static SemaphoreSlim semaphore;
  8. // A padding interval to make the output more orderly.
  9. private static int padding;
  10.  
  11. public static void Main()
  12. {
  13. // Create the semaphore.
  14. semaphore = new SemaphoreSlim(, );
  15. Console.WriteLine("{0} tasks can enter the semaphore.",
  16. semaphore.CurrentCount);
  17. Task[] tasks = new Task[];
  18.  
  19. // Create and start five numbered tasks.
  20. for(int i = ; i <= ; i++)
  21. {
  22. tasks[i] = Task.Run( () => {
  23. // Each task begins by requesting the semaphore.
  24. Console.WriteLine("Task {0} begins and waits for the semaphore.",
  25. Task.CurrentId);
  26. semaphore.Wait();
  27.  
  28. Interlocked.Add(ref padding, );
  29.  
  30. Console.WriteLine("Task {0} enters the semaphore.", Task.CurrentId);
  31.  
  32. // The task just sleeps for 1+ seconds.
  33. Thread.Sleep( + padding);
  34.  
  35. Console.WriteLine("Task {0} releases the semaphore; previous count: {1}.",
  36. Task.CurrentId, semaphore.Release()); } );
  37. }
  38.  
  39. // Wait for half a second, to allow all the tasks to start and block.
  40. Thread.Sleep();
  41.  
  42. // Restore the semaphore count to its maximum value.
  43. Console.Write("Main thread calls Release(3) --> ");
  44. semaphore.Release();
  45. Console.WriteLine("{0} tasks can enter the semaphore.",
  46. semaphore.CurrentCount);
  47. // Main thread waits for the tasks to complete.
  48. Task.WaitAll(tasks);
  49.  
  50. Console.WriteLine("Main thread exits.");
  51. }
  52. }
  53. // The example displays output like the following:
  54. // 0 tasks can enter the semaphore.
  55. // Task 1 begins and waits for the semaphore.
  56. // Task 5 begins and waits for the semaphore.
  57. // Task 2 begins and waits for the semaphore.
  58. // Task 4 begins and waits for the semaphore.
  59. // Task 3 begins and waits for the semaphore.
  60. // Main thread calls Release(3) --> 3 tasks can enter the semaphore.
  61. // Task 4 enters the semaphore.
  62. // Task 1 enters the semaphore.
  63. // Task 3 enters the semaphore.
  64. // Task 4 releases the semaphore; previous count: 0.
  65. // Task 2 enters the semaphore.
  66. // Task 1 releases the semaphore; previous count: 0.
  67. // Task 3 releases the semaphore; previous count: 0.
  68. // Task 5 enters the semaphore.
  69. // Task 2 releases the semaphore; previous count: 1.
  70. // Task 5 releases the semaphore; previous count: 2.
  71. // Main thread exits.

SemaphoreSlim示例

Samaphore实现:https://blog.csdn.net/ma_jiang/article/details/78631038

[.net 多线程]Semaphore信号量的更多相关文章

  1. java多线程-Semaphore信号量使用

    介绍 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 概念 Semaphore分为单值和多值两种,前者 ...

  2. java多线程----Semaphore信号量

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util ...

  3. 多线程锁:Mutex互斥体,Semaphore信号量,Monitor监视器,lock,原子操作InterLocked

    Mutex类 “mutex”是术语“互相排斥(mutually exclusive)”的简写形式,也就是互斥量.互斥量跟临界区中提到的Monitor很相似,只有拥有互斥对象的线程才具有访问资源的权限, ...

  4. java架构之路(多线程)JUC并发编程之Semaphore信号量、CountDownLatch、CyclicBarrier栅栏、Executors线程池

    上期回顾: 上次博客我们主要说了我们juc并发包下面的ReetrantLock的一些简单使用和底层的原理,是如何实现公平锁.非公平锁的.内部的双向链表到底是什么意思,prev和next到底是什么,为什 ...

  5. [Python 多线程] Semaphore、BounedeSemaphore (十二)

    Semaphore 信号量,信号量对象内部维护一个倒计数器,每一次acquire都会减1,当acquire方法发现计数为0就阻塞请求的线程,直到其它线程对信号量release后,计数大于0,恢复阻塞的 ...

  6. Linux多线程编程-信号量

    在Linux中.信号量API有两组.一组是多进程编程中的System V IPC信号量.另外一组是我们要讨论的POSIX信号量. 这两组接口类似,但不保证互换.POSIX信号量函数都已sem_开头,并 ...

  7. 第十五章、Python多线程之信号量和GIL

    目录 第十五章.Python多线程之信号量和GIL 1. 信号量(Semaphore) 2. GIL 说明: 第十五章.Python多线程之信号量和GIL 1. 信号量(Semaphore) 信号量用 ...

  8. [并发编程 - 多线程:信号量、死锁与递归锁、时间Event、定时器Timer、线程队列、GIL锁]

    [并发编程 - 多线程:信号量.死锁与递归锁.时间Event.定时器Timer.线程队列.GIL锁] 信号量 信号量Semaphore:管理一个内置的计数器 每当调用acquire()时内置计数器-1 ...

  9. CountDownLatch 闭锁、FutureTask、Semaphore信号量、Barrier栅栏

    同步工具类可以是任何一个对象.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括信号量(Semaphore).栅栏(Barrier).以及闭锁(Latch). 所有的同步工具类都包含一些特定的结构 ...

随机推荐

  1. RHEL6 64位ASM方式安装oracle 11gR2(二)

    本文转载自:http://vnimos.blog.51cto.com/2014866/1221377 三.安装数据库软件 1 2 3 4 5 6 7 8 # unzip -d /stage/ linu ...

  2. 使用CMake生成sln项目和VS工程遇到的问题

    用vs运行cmake后的工程 参考:http://zhidao.baidu.com/link?url=AZRxI0jGDzo6Pikk68qylee0g7leXbpbZGiVuyiijWbd8scUK ...

  3. 【转】配置Jmeter的自定义参数

    配置Jmeter的自定义参数 User Defined Variables 在这个控件中,定义你所需要的参数,如 在对应的需要使用参数的位置,使用${host}替代. 应用场景: 当测试环境变化时,我 ...

  4. java流类,快速统计出字符次数+++

    总结:学会给一个合适的命名,不要总是abc..虽然简单,但是不容易看懂,和方便去理解 package com.aini; import java.io.File; import java.io.Fil ...

  5. 类的特殊成员方法,类的起源type, metaclass

    1.__doc__表示类的描述信息 2. __module__ 和  __class__  __module__ 表示当前操作的对象在那个模块 __class__     表示当前操作的对象的类是什么 ...

  6. Pycharm快速复制当前行到下一行Ctrl+D

    Pycharm快速复制当前行到下一行Ctrl+D

  7. 分析java类的静态成员变量初始化先于非静态成员变量

    依上图中当class字节码文件被jvm虚拟机加载到内存中依次经过 连接 验证:对字节码进行验证 准备:给静态变量分配内存并赋予变量类型各自的默认值(注:基本类型为0或false,对象为null,sta ...

  8. whoosh----索引|搜索文本类库

    先了解基本概念和步骤: Quick Start Whoosh是一个索引文本和搜索文本的类库,他可以为你提供搜索文本的服务,比如如果你在创建一个博客的软件,你可以用whoosh为它添加添加一个搜索功能以 ...

  9. 14-jQuery的ajax

    什么是ajax AJAX  =  异步的JavaScript 和 XML (Asynchronous Javascript and XML) 简言之,在不重载整个网页的情况下,AJAX通过后台加载数据 ...

  10. JavaScript语言基础-作用域