当前位置: 首页 > news >正文

深入理解 Go 语言信号量 Semaphore

1. 什么是信号量

        信号量的概念是荷兰计算机科学家 Edsger Wybe Dijkstra 在 1963 年左右提出来的,被广泛应用在不同的操作系统中。在操作系统中,会给每一个进程分配一个信号量,代表每个进程目前的状态。未得到控制权的进程,会在特定的地方被迫停下来,等待可以继续进行的信号到来。

        Edsger Wybe Dijkstra (1930-2002) 是一位荷兰计算机科学家和数学家,被认为是计算机科学领域的先驱之一。他在计算机科学的发展史上发挥了重要作用,他提出的算法和思想对计算机科学和软件工程产生了深远影响。

        Dijkstra 最为著名的贡献之一是开发了 Dijkstra 算法,它是一种在图形网络中找到最短路径的算法,被广泛应用于网络路由和其他领域。他还发明了一种名为 “信号量” 的同步机制,为并发网络编程提供了一种重要的工具。此外,他还对程序设计语言的诘法和结构进行了深入的研究,为编程语言的设计和实现提供了许多有价值的建议。

        Dijkstra 也是一位重要的教育家和思想家,他强调了对计算机科学教育的重视和深入思考的重要性。他在其许多著作和演讲中都强调了算法与程序设计的重要性,并强调了开发高质量软件的必要性。

        Dijkstra 在他的职业生涯中获得了许多荣誉,包括图灵奖、IEEE 计算机协会的计算机科学和工程奖、ACM SIGPLAN 的系统软件奖等。他去世后,他的贡献得到了计算机科学领域的广泛赞誉和纪念。

        最简单的信号量是一个变量加一些并发控制的能力,这个变量是 0 到 n 之间的一个值。当 goroutine 完成对此信号量的等待(wait) 时,该计数值就减 1 ;当 goroutine 完成对此信号量的释放 (release) 时,该计数值就加 1。当计数值为 0 时, goroutine 调用 wait 等待该信号量是不会成功的,除非计数值又大于 0 ,等待的 goroutine 才有可能成功返回。 

1.1 P/V 操作

        Dijkstra 在他的论文中为信号量定义了两个操作 : P 和 V 。P 操作(如 decrease、wait、acquire) 用减小信号量的计数值,V 操作(如 increase、signal、release)则用来增大信号量的计数值。

        P ( passeren)在荷兰语中表示 “通过” ,V (vrijigeven) 在荷兰语中表示 “释放”,这也许就是 Dijkstra 把它们叫做 P/V 操作的原因。

        使用伪代码表示如下(方括号代表原子操作):

function V(semaphore S, integer I):function P(semaphore S,integer I):repeat:[if S ≥I:break]

        可以看到,初始化的信号量 S 有一个指定数量 (n) 的资源,它就像一个有 n 个资源的池子。P 操作相当于请求资源,如果有足够的资源可用,则立即返回;如果没有资源或者资源不够,那么它可以不断地尝试或者被阻塞等待。 V 操作相当于释放资源,把资源返还给信号量。信号量的值只能由 P/V 操作改变(初始化操作除外)。

现在,我们来总结一下信号量的实现。

  • 初始化信号量:设定资源的初始数量。
  • P 操作:将信号量的计数值减 k,如果新值为负数,那么调用者会被阻塞并加入等待队列中;否则,调用者会继续执行,并且获得 k 个资源。
  • V 操作:将信号量的计数值加 k, 如果先前的计数值为负数,则说明有等待的 P 操作的调用者。 V 操作会从等待队列中取出一个等待的调用者,唤醒它,让它继续执行。
1.2 信号量和互斥锁的区别与联系

        信号量有两种类型:二元信号量和计数信号量。其中,二元信号量只有两个值,通常是 0 和 1,它用于

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 数据库事务( 五 ) Spring管理事务的几道面试题
  • 史上最详细ArduinoESP32 外部中断
  • python爬虫学习记录-请求模块urllib3
  • lvs实战项目-dr模式实现
  • github使用gh-pages部署vue静态网站(简单易懂)
  • gorm不定参数
  • 第129天:内网安全-横向移动WmiSmbCrackMapExecProxyChainsImpacket
  • SOPHGO算能科技BM1684盒子占用空间满的问题解决
  • AI大模型加持的新一代网络舆情系统——“速途观澜”舆情感知引擎发布上线
  • Hadoop的streamingAPI与MapReduce[Python]
  • 使用 NumPy 生成随机数:一个全面的指南
  • ASC格式的协议数据解析
  • 使用Anaconda安装多个版本的Python并与Pycharm进行对接
  • 为企业创建智能支持 AI 代理
  • RTOS(8)信号量和互斥量
  • 【刷算法】求1+2+3+...+n
  • Angular 4.x 动态创建组件
  • CentOS7 安装JDK
  • conda常用的命令
  • CSS居中完全指南——构建CSS居中决策树
  • exif信息对照
  • Java深入 - 深入理解Java集合
  • JS学习笔记——闭包
  • Laravel核心解读--Facades
  • Less 日常用法
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • SQLServer之创建显式事务
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 分享几个不错的工具
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 那些年我们用过的显示性能指标
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 提醒我喝水chrome插件开发指南
  • 新手搭建网站的主要流程
  • 新书推荐|Windows黑客编程技术详解
  • Mac 上flink的安装与启动
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • UI设计初学者应该如何入门?
  • 数据库巡检项
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #Datawhale AI夏令营第4期#AIGC方向 文生图 Task2
  • #微信小程序:微信小程序常见的配置传值
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (1)SpringCloud 整合Python
  • (HAL库版)freeRTOS移植STMF103
  • (差分)胡桃爱原石
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (四)React组件、useState、组件样式
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)c++ std::pair 与 std::make