Semaphore的工作原理,与Mutex有何区别?
在计算机科学中,semaphore是一种变量或抽象数据类型,用于控制并发系统(如多任务操作系统)中多个进程对公共资源的访问。一个semaphore就是一个简单的变量。在多进程环境下,这个变量用来解决关键部分问题,实现进程同步。琐碎的信号体是一个普通的变量,它根据程序员定义的条件而改变(例如增量或减量或切换)。
将现实世界系统中使用的semaphore作为特定资源的多少个单位可用的记录,再加上在资源单位获得或空闲时安全地调整该记录(即避免竞赛条件)的操作,如果必要的话,等到资源的一个单位变得可用。
Semaphores是防止竞赛条件的有用工具。允许任意资源计数的semaphore称为计数semaphore,而限制为0和1(或锁定/解锁、不可用/可用)的semaphore称为二进制semaphore,用于实现锁。
1 图书馆自习室案例
假设某图书馆有10间相同的自习室,每次供一名学生使用。如果学生想使用自习室,必须向前台申请一个房间。如果没有空房间,学生就在前台等待,直到有人让出房间。当学生使用完一个房间后,必须回到服务台,并告知有一个房间空闲。
在最简单的实现中,前台的管理员只需要知道可用的房间数量。当学生申请房间时,管理员会减少这个数字。 当学生释放房间时,管理员会增加这个数字。
在这个场景中,前台的管理员代表一个计数semaphore,房间是资源,学生代表进程或者线程。在这个场景中,semaphore的值最初是10,所有房间都是空的。当一个学生请求房间时,计数不为零被允许访问,semaphore的值被改为9。下一个学生来了之后,它就会降到8,然后是7,以此类推。如果有人请求一个房间,而当前semaphore的值为0时,此人需要等待,直到一个房间被释放时,计数大于零。如果其中一个房间被释放了,但有几个学生在等待,那么可以使用任何方法来选择占据这个房间的人(比如FIFO或掷硬币)。当然,学生需要在真正离开房间后才通知管理员增加计数,否则,当学生在离开房间的过程中(如正在收拾课本时),另一个学生进入房间就会出现尴尬的情况。
2 资源规则
当用于控制对资源池的访问时,Semaphore只跟踪有多少资源是空闲的;它不跟踪哪些资源是空闲的。此处可能需要一些其他机制来选择一个特定的空闲资源。
这个范式特别强大,因为semaphore计数可以作为一些不同行动的触发器。上面的图书管理员可能会在自习室没有剩余学生的时候关灯,或者在大部分房间都有人的时候,放置一个写着房间繁忙的标志。
规程的成功需要申请者正确遵守。如果哪怕是一个程序的行为不正确,公平性和安全性都有可能受到影响(这实际上意味着一个程序可能会表现缓慢、行为不稳定、挂起或崩溃)。这包括
1. 请求一个资源却在用完后忘记释放,
2. 释放一个从未被请求的资源。
3. 长时间持有一个资源而不用。
4. 在没有先请求资源(或释放资源后)的情况下使用资源。
即使所有的进程都遵循这些规则,当有不同的资源由不同的semaphores管理,以及当进程需要同时使用一个以上的资源时,多资源死锁仍然可能发生。
3 语义和实施
计数Semaphore有两个操作,历史上称为P和V。操作V使Semaphore 递增,操作P使其递减。
Semaphore的值是该资源当前可用的单位数。P操作会等待直到一个受保护的资源变得可用时才会进行递减。V操作则是反过来:它在进程使用完资源后会增加计数再次使资源可用。Semaphore的一个重要特点是它的值只能通过V和P操作改变。
P, V操作可以是如下的原子操作:
function V(semaphore S, integer I):
[S ← S + I]
function P(semaphore S, integer I):
repeat:
[if S ≥ I:
S ← S − I
break]
一个semaphore有一个相关的进程队列(具有FIFO规则)。 如果一个进程对一个值为0的semaphore执行了P操作,那么这个进程就会被添加到semaphore的队列中,并暂停其执行。当另一个进程通过执行V操作来增加Semaphore, 而队列上有进程时,其中一个进程会被从队列中移除并恢复执行。当进程具有不同的优先级时,可以按优先级对队列进行排序,使优先级最高的进程先从队列中取出。
4 Semaphores vs. mutexes
Mutex是一种锁定机制,其基本实现与二进制Semaphore相同。
它们之间的区别在于如何使用它们。
虽然二进制Semaphore可以被通俗地称为mutex,但真正的mutex有一个更具体的使用情况和定义,即只有锁定mutex的任务才应该解锁它。这个约束的目的是为了处理使用Semaphore的一些潜在问题:
1. 优先级倒置。
如果mutex知道是谁锁定了它,并且应该解锁它,那么每当一个更高优先级的任务开始等待mutex时,就有可能提升该任务的优先级
2. 任务过早终止。
Mutex还可以提供删除安全保障,即持有mutex的任务不会被意外删除。
3. 终止死锁。
如果一个持有mutex的任务因任何原因终止,操作系统可以释放该条件的mutex和信号等待任务。
4. 递归死锁。
一个任务可以多次锁定一个重入的mutex,因为它解锁的次数相等。
5. 意外释放。
如果释放任务不是其所有者,则在释放mutex时出现错误。
5 参考
https://en.wikipedia.org/wiki/Semaphore_(programming)
https://en.wikipedia.org/wiki/Flag_semaphore
https://en.wiktionary.org/wiki/semaphore
https://www.geeksforgeeks.org/semaphores-in-process-synchronization/
https://www.geeksforgeeks.org/mutex-vs-semaphore/
- 点赞
- 收藏
- 关注作者
评论(0)