五分钟了解Semaphore
一、前言
多个线程之间的同步,我们会用到Semaphore,翻译成中文就是信号量。使用Semaphore可以限制多个线程对同一资源的访问。我们先看下C#中对Semaphore的定义,如下图:

翻译成中文就是:

个人理解就是线程之间靠这个信号量完成通信。比如B线程必须要等A线程完成后才能工作,也可以用来控制并发的线程数,下面我们看具体的例子,代码如下:

上面代码先声明了一个Semaphore对象,构造函数中Semaphore(3,3)表示初始线程数和最大线程数,表示对同一资源的访问,最多同时允许3个线程并发执行,运行结果如下:

如果我们将值改为Semaphore(5,5),则表示可以同时并发执行5个线程,运行结果如下:

我们看到线程执行方法的第一行代码为semaphore.WaitOne(),会判断当前信号量,如果当前信号量大于0则继续执行,如果等于0则会阻塞当前线程并将信号量减1(当前为-1),直到有线程释放并将信息号。注释截图如下:

当其他线程执行完成后,执行代码semaphore.Release(),此时会将信号量加1,如果加完后信号量的值小于或等于0,则会唤醒一个阻塞在该信号量上的线程。注释截图如下:

二、原理
个人对Semaphore的理解其实比较简单,就是规定对一个公有资源同时可操作的最大线程数,wait执行数量减1操作,signal执行数量加1操作,且这两个操作由操作系统保证原子性。我们可以先看一段伪代码,如下:

代码解读:
wait(),申请资源,对信号量做减1操作,减完后如果值小于0,表示资源已经分配完,进行阻塞等待。
signal(),释放资源,对信号量做加1操作,加完后如果值小于等于0,则唤醒等待的线程并执行。
<完>
更多精彩文章,可关注我的公众号:

五分钟了解Semaphore的更多相关文章
- 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...
- [分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例)
[分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例) 踏雁寻花 发表于 2015-8-23 23:31:28 https://www.itsk.com/thread-35 ...
- JVM内存管理------GC算法精解(五分钟让你彻底明白标记/清除算法)
相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...
- 转帖:用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树 这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托 ...
- 《sort帮你排序》-linux命令五分钟系列之二十六
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之四》-linux命令五分钟系列之二十四
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之三》-linux命令五分钟系列之二十三
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之二》-linux命令五分钟系列之二十二
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 《sed的流艺术之一》-linux命令五分钟系列之二十一
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
随机推荐
- Dcoker跨主机容器通信之overlay
同样是两台服务器: 准备工作: 设置容器的主机名 consul:kv类型的存储数据库(key:value) docker01.02上: vim /etc/docker/daemon.json { &q ...
- cesium入门示例-3dTiles加载
数据转换工具采用cesiumlab1.5.17版本,转换后的3dTiles加载显示比较简单,通过Cesium.Cesium3DTileset接口指定url即可,3dTiles文件可与js前端代码放置一 ...
- 吴裕雄--天生自然 人工智能机器学习实战代码:ELASTICNET回归
import numpy as np import matplotlib.pyplot as plt from matplotlib import cm from mpl_toolkits.mplot ...
- Hessian简介
Hessian Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为 ...
- centos7开启ntp并同步时间到指定时区
前提:近期公司都是使用的直接对外的云服务器,在登上服务器后用date命令查看新服务器的时间,发现并不是标准时间,于是需要做时间同步.我这里讲的是能连接外网的情况下,在服务器不多的情况下是否此方法,大型 ...
- 百度测试架构师眼中的百度QA
百度测试架构师眼中的百度QA(一) 发表于2013-04-09 15:31| 4004次阅读| 来源架构师Jack的个人空间| 13 条评论| 作者董杰 百度测试QA 摘要:一直以来百度质量部在业 ...
- 解密JDK8 枚举
写一个枚举类 1 2 3 4 5 6 public enum Season { SPRING, SUMMER, AUTUMN, WINTER } 然后我们使用javac编译上面的类,得到class文件 ...
- kafka&&kafka-manager部署安装
一.zk集群部署 二.kafka部署安装 1.创建kafka用户和日志路径,(直接执行) groupadd kafka useradd -g kafka kafka mkdir -p /web/kaf ...
- Android中Intent的各种常见作用。
Android开发之Intent.Action 1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开始. ...
- JAVA中对list map根据map某个key值进行排序
package test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; ...