网站首页 > 教程文章 正文
什么是信号量(Semaphore)?
信号量是一种用于线程同步的机制,允许多个线程同时访问一定数量的共享资源。信号量通过计数器来控制线程的访问量。
- 计数器含义:
信号量的计数器表示可以被线程访问的共享资源数量:当一个线程获取信号量时,计数器减 1。当线程释放信号量时,计数器加 1。 - 信号量种类:二进制信号量(Binary Semaphore): 计数器只有 0 和 1,类似于互斥锁。计数信号量(Counting Semaphore): 计数器可以是任意非负值,用于限制对资源的并发访问。
 
信号量的作用
- 控制访问数量:
限制对共享资源的并发访问。例如,控制线程池的最大线程数、限制数据库连接的最大并发数等。 - 实现同步:
在线程间传递信号,确保某些操作完成后再执行后续操作。 
如何使用信号量实现线程同步?
在 C# 中,信号量可以通过 Semaphore 或 SemaphoreSlim 类实现:
- Semaphore: 用于跨进程的信号量,较为重型。
 - SemaphoreSlim: 仅适用于进程内的轻量级信号量,推荐用于大多数场景。
 
代码示例:限制线程访问共享资源
以下示例展示如何使用 SemaphoreSlim 限制线程并发访问共享资源的数量。
using System;
using System.Threading;
class Program
{
    private static SemaphoreSlim semaphore = new SemaphoreSlim(3); // 最大并发线程数为 3
    static void AccessResource(int threadNumber)
    {
        Console.WriteLine(#34;Thread {threadNumber} is waiting to access the resource...");
        semaphore.Wait(); // 获取信号量
        try
        {
            Console.WriteLine(#34;Thread {threadNumber} is accessing the resource.");
            Thread.Sleep(2000); // 模拟资源访问
        }
        finally
        {
            Console.WriteLine(#34;Thread {threadNumber} has released the resource.");
            semaphore.Release(); // 释放信号量
        }
    }
    static void Main(string[] args)
    {
        for (int i = 1; i <= 10; i++)
        {
            int threadNumber = i;
            new Thread(() => AccessResource(threadNumber)).Start();
        }
        Console.ReadLine();
    }
}
代码解析
- 创建信号量:
 - private static SemaphoreSlim semaphore = new SemaphoreSlim(3);
 - SemaphoreSlim(3) 指定信号量的初始计数为 3,表示最多允许 3 个线程同时访问资源。
 - 获取信号量:
 - semaphore.Wait();
 - 线程调用 Wait() 时,会尝试获取信号量:
 - 如果信号量计数器大于 0,则计数器减 1,线程进入临界区。
 - 如果计数器为 0,则线程阻塞等待。
 - 释放信号量:
 - semaphore.Release();
 - 线程完成任务后调用 Release(),信号量计数器加 1,其他等待的线程可以继续运行。
 - 并发限制: 即使我们创建了 10 个线程,但同时最多只有 3 个线程可以访问资源,其他线程需要等待。
 
信号量的应用场景
- 数据库连接池: 限制同时连接到数据库的客户端数量。
 - 线程池管理: 控制线程池中同时运行的任务数量。
 - 文件访问: 防止多个线程同时写入文件导致数据不一致。
 - 资源分配: 如网络连接或硬件资源的限量使用。
 
小结
- 信号量的核心作用是控制对共享资源的并发访问。
 - SemaphoreSlim 是轻量级的信号量实现,推荐用于进程内的线程同步。
 - 在多线程编程中,信号量可以有效避免资源争用问题,同时灵活控制线程的并发量,提升程序稳定性和效率。
 
猜你喜欢
- 2024-12-26 进程间通信:共享内存和信号量的统一封装机制原理与实现
 - 2024-12-26 python基础篇:多线程的基本使用 python3.9多线程
 - 2024-12-26 介绍C#中的并发集合,并说明其在多线程编程中的作?
 - 2024-12-26 Hystrix系列之信号量、线程池 信号量 线程池
 - 2024-12-26 劳斯莱斯推出独一无二的Spectre Semaphore:车头泼墨,极致奢华
 - 2024-12-26 Linux信号量(1)-SYSTEM V Linux信号量做进程同步
 - 2024-12-26 什么是多线程同步?请列举多种多线程同步机制并?较它们的优缺点
 - 2024-12-26 2 万字长文详解 10 大多线程面试题|原力计划
 - 2024-12-26 进程间通信——POSIX 有名信号量与无名信号量
 - 2024-12-26 Python并发编程:使用信号量Semaphore实现资源有限的并发场景
 
- 最近发表
 
- 标签列表
 - 
- location.href (44)
 - document.ready (36)
 - git checkout -b (34)
 - 跃点数 (35)
 - 阿里云镜像地址 (33)
 - qt qmessagebox (36)
 - mybatis plus page (35)
 - vue @scroll (38)
 - 堆栈区别 (33)
 - 什么是容器 (33)
 - sha1 md5 (33)
 - navicat导出数据 (34)
 - 阿里云acp考试 (33)
 - 阿里云 nacos (34)
 - redhat官网下载镜像 (36)
 - srs服务器 (33)
 - pico开发者 (33)
 - https的端口号 (34)
 - vscode更改主题 (35)
 - 阿里云资源池 (34)
 - os.path.join (33)
 - redis aof rdb 区别 (33)
 - 302跳转 (33)
 - http method (35)
 - js array splice (33)
 
 
