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

【多线程】信号量(Semaphore)常见的应用场景

【多线程】信号量(Semaphore)常见的应用场景

本文来自于我关于多线程系列文章。欢迎阅读、点评与交流
1.【多线程】信号量(Semaphore)是什么?
2.【多线程】信号量(Semaphore)常见的应用场景

信号量(Semaphore)是一种非常重要的同步机制,由荷兰计算机科学家Dijkstra提出。它的核心是一个计数器,用于控制多个线程(或进程)对有限数量共享资源的访问。

信号量的主要应用场景可以分为以下几大类:

1. 互斥(Mutex / Binary Semaphore)

这是最基础、最常见的应用场景。二进制信号量(其值只能为0或1)常被用作互斥锁,以确保在任何时刻只有一个线程可以访问临界区。

  • 核心思想:保护一段代码(临界区),防止多个线程同时进入。

  • 工作方式

    • 信号量初始值为1,表示锁是可用的。
    • 线程进入临界区前执行 wait()(或 P())操作,将信号量减为0。
    • 其他线程再执行 wait() 时会被阻塞,因为信号量已经是0。
    • 拥有锁的线程退出临界区后执行 signal()(或 V())操作,将信号量恢复为1,唤醒一个等待的线程。
  • 应用实例

    • 多线程操作共享数据:例如,多个线程同时更新一个全局变量、一个链表或一个共享文件。使用信号量可以避免数据竞争和不一致。
    • 访问共享硬件:如只有一个打印机,多个进程需要排队打印。

2. 同步(Synchronization)

信号量可以用于线程或进程间的执行顺序同步,确保一个操作必须在另一个操作完成之后才能开始。这通常使用计数信号量(初始值常为0)。

  • 核心思想:一个线程等待另一个线程完成某个任务后发出的“信号”。

  • 工作方式

    • 线程A需要等待线程B完成某项工作。
    • 信号量初始化为0。
    • 线程A在需要等待的地方执行 wait(),由于初始值为0,它会被阻塞。
    • 线程B完成任务后,执行 signal(),将信号量加1。
    • 线程A被唤醒,继续执行。
  • 经典模型:生产者-消费者问题

    • 场景:一个或多个生产者线程生产数据并放入缓冲区,一个或多个消费者线程从缓冲区取出数据消费。
    • 需要的信号量
      1. 互斥信号量(mutex):初始值为1,用于保证任何时候只有一个线程(生产者或消费者)操作缓冲区。
      2. 空位信号量(empty):初始值为缓冲区的总大小(N),表示当前可用的空位数量。生产者生产前需要获取一个空位(wait(empty)),消费者消费后会释放一个空位(signal(empty))。
      3. 满位信号量(full):初始值为0,表示当前缓冲区中可供消费的数据项数量。消费者消费前需要获取一个满位(wait(full)),生产者生产后会释放一个满位(signal(full))。
  • 其他应用实例

    • 线程A等待线程B完成初始化
    • 主线程等待所有工作线程完成任务后再进行汇总

3. 控制对资源池的访问(Resource Pool)

当有一组数量固定的同类资源(如数据库连接池、内存缓冲区块、线程池中的工作线程)时,可以使用计数信号量来管理对这些资源的分配。

  • 核心思想:信号量的初始值设置为资源的总数。
  • 工作方式
    • 线程需要资源时,执行 wait(),信号量值减1。如果值大于0,立即获取资源;如果值等于0,则阻塞直到有资源被释放。
    • 线程释放资源时,执行 signal(),信号量值加1,并唤醒一个可能正在等待资源的线程。
  • 应用实例
    • 数据库连接池:系统启动时创建10个数据库连接。信号量初始值为10。任何需要数据库操作的线程必须先从信号量获取一个“许可”,使用完毕后释放。
    • 内存池管理

4. 限制并发数(Throttling / Rate Limiting)

这个场景与控制资源池类似,但目的略有不同。它不是为了管理具体的物理资源,而是为了限制系统某一部分的负载,防止系统过载。

  • 核心思想:设置一个并发上限。
  • 工作方式
    • 信号量初始值设置为允许的最大并发数(例如100)。
    • 每当一个任务开始执行时,先执行 wait()
    • 当任务执行完毕时,执行 signal()
    • 如果当前已有100个任务在运行,第101个任务在执行 wait() 时会被阻塞,直到有任务完成。
  • 应用实例
    • 限制同时处理的HTTP请求数量,防止服务器崩溃。
    • 限制同时发起的API调用次数,以遵守第三方服务的速率限制。

总结

应用场景信号量类型初始值核心目的
互斥(Mutex)二进制信号量1保护临界区,一次只允许一个线程进入
同步(如生产者-消费者)计数信号量0 或 N协调线程间的执行顺序
资源池管理计数信号量资源总数高效、安全地分配有限资源
限制并发数计数信号量并发上限流量控制,防止系统过载

重要提示:在现代编程中(如Java的 synchronized 关键字、java.util.concurrent.locks.ReentrantLock 或Python的 threading.Lock),实现互斥时更推荐使用专门的互斥锁(Mutex),因为它们通常具有所有权概念(防止其他线程释放锁)等更安全的特性。而信号量(特别是计数信号量)在实现复杂的同步模式(如生产者-消费者)和控制并发访问数量方面,仍然具有不可替代的优势。

http://www.dtcms.com/a/400091.html

相关文章:

  • 注册网站账号违法吗莱芜最好的网站建设公司
  • seo关键词排名技巧网站诊断网站seo诊断
  • 月饼杯(web全解)
  • 临床研究三千问——临床研究体系的5库(10)
  • 邢台装修网站建设软件开发八个阶段
  • 烟台网站建设公司地址婚纱摄影网站建设
  • 网站开发培训视频400靓号手机网站建设
  • 百度云加速 网站关键词ftp服务器搭建设置网站信息
  • 打通数字孪生项目的“最后一公里”:筑牢行业智能数字地基,重构产业落地敏捷基因
  • 新乡建设招标投标网站捕鱼游戏源码论坛
  • 路径规划智能小车(论文+源码)
  • 犀牛云网站建设wordpress插件dflip
  • 11.vector的模拟实现
  • 可以在什么网站做二建题目wordpress插件出错
  • 0716网站建设php图书管理系统网站开发
  • 做电子板报的网站企业宣传册文案范文
  • 深圳做公司网站推广的太原网站建设名录
  • 营口电商网站建设企业模板网站vue
  • python基本程序要素
  • 做镜像网站利润用ps怎么做网站背景
  • 中移物联ML307C模组OPENCPU笔记2
  • 专业网站制作公司排名网站建设底部
  • 优选算法---滑动窗口 题目及算法分析 代码实现
  • 做水果网站首页的图片素材免费空间使用指南
  • 基于SpringBoot的实习管理系统设计与实现
  • 47. 全排列 II
  • ru后缀的网站百度搜索怎么优化
  • 自己做的网站无法访问php网站开发最低配置
  • 手机如何做车载mp3下载网站网站都需要续费吗
  • Linux常用命令52——head显示文件开头的内容