信号量跟内部锁有什么区别?

本文比较了内部锁和信号量在多线程编程中的不同:内部锁为二元状态,粗粒度,仅限一个线程访问;信号量则提供多元状态和灵活粒度,支持多线程并发,适用于资源池管理等复杂场景。

信号量和内部锁(也称为互斥锁)是两种不同的同步机制,用于管理多线程环境中的并发访问问题。它们之间的主要区别在于控制对共享资源的访问的方式和粒度。

内部锁(互斥锁):

  1. 粒度: 内部锁是一种较为粗粒度的同步机制。当一个线程获得了内部锁,其他线程就不能同时访问被保护的代码块或资源。这种锁的作用范围通常是一个整个方法或一个代码块。

  2. 二元状态: 内部锁是一种二元状态的同步机制,即锁处于锁定状态或解锁状态。一次只有一个线程可以持有锁,其他线程必须等待锁的释放。

  3. 递归: 内部锁通常支持线程的递归获取。即,同一个线程可以多次获取同一个锁,而不会造成死锁。

信号量:

   1.粒度: 信号量提供了一种更灵活的同步机制,可以控制对资源的访问粒度。信号量的计数值可以大于1,允许多个线程同时访问共享资源。计数值为1时,信号量的行为类似于内部锁。

   2.多元状态: 信号量是一种多元状态的同步机制。信号量的计数值表示可用资源的数量,多个线程可以同时获取资源,直到计数值减为零。

  3. 非占有: 信号量不要求线程必须先获取锁,可以直接尝试获取资源。这使得信号量更适用于一些特定的并发场景,如控制资源池中的资源分配。

区别总结:

         选择使用内部锁还是信号量取决于具体的并发需求和程序设计的复杂性。

  1. 内部锁是一种二元状态、粗粒度的同步机制,只允许一个线程同时访问被保护的代码块或资源。
  2. 信号量是一种多元状态、更灵活的同步机制,允许多个线程同时访问共享资源,具有更细粒度的控制。
  3. 内部锁适用于简单的互斥场景,而信号量适用于需要更复杂控制的并发场景,例如资源池管理。
### **互斥/信号量放在结构体内 vs 结构体外的区别** #### **1. 作用域与生命周期** | **存放位置** | **作用域** | **生命周期** | |---------------------|------------------------------|-----------------------------| | **结构体内** | 绑定到结构体实例 | 随结构体实例创建/销毁而存在 | | **结构体外(全局)** | 全局或模块级作用域 | 独立于结构体,需手动管理 | #### **2. 并发控制粒度** - **结构体内** - **细粒度**:每个结构体实例拥有独立的,适合多实例并发(如每个文件描述符一个)。 - 示例: ```c struct my_data { int value; struct mutex lock; // 每个实例有自己的 }; ``` - **结构体外** - **粗粒度**:全局保护所有实例,可能成为性能瓶颈(如全局资源竞争)。 - 示例: ```c struct mutex global_lock; // 所有实例共享同一 struct my_data { int value; }; ``` #### **3. 内存开销** - **结构体内**:每个实例占用额外内存(变量),但可避免争用。 - **结构体外**:仅需一个,但可能因竞争导致延迟。 #### **4. 典型应用场景** - **结构体内** - 需要保护结构体内部字段(如链表节点、设备状态)。 - 示例:内核的 `struct inode`(每个inode自带)。 - **结构体外** - 保护全局资源(如全局链表、共享硬件寄存器)。 - 示例:`mmap_sem`(保护整个内存映射树)。 #### **5. 代码可维护性** - **结构体内**:与数据绑定,逻辑清晰,但需确保初始化/释放正确。 - **结构体外**:需显式管理的归属,容易误用(如未配对释放)。 --- ### **示例对比** #### **(1)在结构体内(推荐多数场景)** ```c struct device { int status; struct mutex lock; // 每个设备独立 }; void update_device(struct device *dev) { mutex_lock(&dev->lock); dev->status = 1; mutex_unlock(&dev->lock); } ``` #### **(2)在结构体外(谨慎使用)** ```c struct mutex dev_lock; // 全局 struct device { int status; }; void update_device(struct device *dev) { mutex_lock(&dev_lock); // 所有设备共用同一 dev->status = 1; mutex_unlock(&dev_lock); } ``` --- ### **如何选择?** | **考虑因素** | **选择结构体内** | **选择结构体外** | |----------------------|------------------------------|----------------------------| | **数据独立性** | 高(实例间无竞争) | 低(全局资源) | | **性能需求** | 高并发场景(如网络套接字) | 低频访问(如初始化) | | **代码复杂度** | 需为每个实例初始化 | 只需管理一个 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值