热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入解析信号量(Semaphore)与互斥锁(Mutex)的原理与应用

互斥锁(MutualExclusion,简称Mutex)是多线程编程中的一种同步机制,用于确保同一时间只有一个线程能够访问共享资源,从而避免数据竞争和不一致的问题。信号量(Semaphore)则是一种更为通用的同步工具,不仅能够控制对资源的访问,还能管理资源的数量。本文将深入探讨这两种机制的工作原理、应用场景以及它们在实际开发中的优缺点,帮助读者更好地理解和使用这些重要的并发控制手段。

互斥锁(英语:英语:Mutual exclusion,缩写 Mutex)是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制。该目的通过将代码切片成一个一个的临界区域(critical section)达成。临界区域指的是一块对公共资源进行访问的代码,并非一种机制或是算法。一个程序、进程、线程可以拥有多个临界区域,但是并不一定会应用互斥锁。

需要此机制的资源的例子有:旗标队列计数器中断处理程序等用于在多条并行运行的代码间传递数据、同步状态等的资源。维护这些资源的同步、一致和完整是很困难的,因为一条线程可能在任何一个时刻被暂停(休眠)或者恢复(唤醒)。

例如:一段代码(甲)正在分步修改一块数据。这时,另一条线程(乙)由于一些原因被唤醒。如果乙此时去读取甲正在修改的数据,而甲碰巧还没有完成整个修改过程,这个时候这块数据的状态就处在极大的不确定状态中,读取到的数据当然也是有问题的。更严重的情况是乙也往这块地方写数据,这样的一来,后果将变得不可收拾。因此,多个线程间共享的数据必须被保护。达到这个目的的方法,就是确保同一时间只有一个临界区域处于运行状态,而其他的临界区域,无论是读是写,都必须被挂起并且不能获得运行机会。

 

一、Semaphore(旗语)

1. 信号量是一个非负整数,具有两种原子操作:

a. P操作:

也称Down操作。等待信号量变为正数,而后减少信号量;等待信号量的值变为正数,而后减少信号量的值,并将此进程列入等待进程列表,阻塞当前进程。

 

b. V操作:也称Up操作。增加信号量,唤醒等待队列中的进程

V操作增加信号量的值,并从等待队列中,去除队列顶部的进程,唤醒其继续执行。

 

二、Mutex(互斥)

1. 一个Lock被确定的一个线程拥有,只有拥有者线程才能操作Lock:

2. Acquire操作:
请求一个Lock,该Lock必须由当前线程拥有。使得当前线程进入挂起状态,直到该Lock被释放。

 

二、区别和联系

两者最大区别:信号量可以允许多个线程进入临界区,而互斥体只允许一个线程进入临界区

1. 初始状态不一样:Mutex的初始值是1(表示锁可用),而Semaphore的初始值是0,随后的操作基本一样。

2. 用法不一样:Mutex的使用者必须为同一个线程,即必须成对使用。而Semaphore可以由不同的线程进行PV操作,即可以由一个线程不停的P一个资源,而另一个线程不停地V一个资源,故可以应用于生产者-消费者模型等资源同步的场合。因此,Mutex又不同于一个二值的Semaphore

 

四、理解SemaphoreMutex
Mutex
是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。
Semaphore
是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore。一般的用法是,用于限制对于某一资源的同时访问。

 

建议mutex只用于保护critical section。而semaphore则用于保护某变量,或者同步。


推荐阅读
author-avatar
钻探paz_106
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有