互斥与 Semaphore – 它们之间的区别

Mutex 和 Semaphore

  • 互斥锁是一种锁定机制,而 Semaphore 是一种信号机制
  • Mutex 只是一个对象,而 Semaphore 是一个整数
  • 互斥锁没有子类型,而信号量有两种类型:计数信号量和二进制信号量。
  • Semaphore 支持等待和信号操作修改,而 Mutex 只能由可能请求或释放资源的进程修改。
  • Semaphore 使用wait()和signal()操作来修改value,另一方面,使用Mutex操作来锁定或解锁。

Mutex 和 Semaphore
Mutex 和 Semaphore

这里我分析了Mutex和 Semaphore 并将综合评估其优缺点。

关于 Mutex 和 Semaphore

根据我的实践,以下是有关 Mutex 和 Semaphore:

  • 只有一个任务可以获得互斥锁。因此,互斥锁具有所有权,只有所有者才能释放它。
  • 使用互斥锁和信号量的原因不同,可能是因为它们的实现相似,互斥锁被称为二进制信号量。
  • 一个众所周知的误解是互斥锁和 Semaphore几乎相同,唯一的区别是 Mutex 可以计数到 1,而 Semaphore能够从 0 数到 N。
  • 二进制信号量和互斥量之间总是存在不确定性。您可能会听说互斥量是二进制信号量,这是不正确的。

什么是 Semaphore?

信号量 只是一个非负变量,在线程之间共享。信号量是一种信号机制,等待信号量的线程可以由另一个线程发出信号。它使用两个原子操作,1) 等待和 2) 发出信号 进程同步.

A 信号 允许或禁止访问资源,这取决于如何设置。

用于 Semaphore

对于单缓冲区的情况,我们可以将4 KB缓冲区分成四个1 KB缓冲区。 Semaphore 可以与这四个缓冲区关联。这样用户和生产者就可以同时在不同的缓冲区上工作。

的优点 Semaphore

在我的实践中,使用信号量的主要优点如下:

  • 它允许多个线程访问临界区
  • Semaphore与机器无关。
  • Semaphore是在微内核的机器独立代码中实现的。
  • 它们不允许多个进程进入临界区。
  • 由于信号量中有一个繁忙的等待计划,因此永远不会浪费进程时间和资源。
  • 它们是与机器无关的,应该在微内核的机器无关代码中运行。
  • 它们允许灵活地管理资源。

缺点 Semaphores

下面是我所遇到的信号量的缺点。

  • 信号量的最大限制之一是优先级反转。
  • 操作系统必须跟踪所有等待和信号信号量的调用。
  • 它们的使用从未被强制执行,而只是按照惯例。
  • 为了避免信号量中的死锁,Wait 和 Signal 操作需要按照正确的顺序执行。
  • Semaphore 编程是一种复杂的方法,因此有可能无法实现互斥。
  • 这也不是一种适合大规模使用的实用方法,因为使用它们会导致模块化的丧失。
  • Semaphore 更容易出现程序员错误。
  • 可能导致 僵局 或由于程序员错误而违反互斥规定。

什么是互斥体?

Mutex 的全称是互斥对象。它是一种特殊类型的二进制信号量,用于控制对共享资源的访问。它包含一个优先级继承机制,以避免扩展优先级反转问题。它允许当前优先级较高的任务在尽可能短的时间内处于阻塞状态。然而,优先级继承并不能纠正优先级反转,而只能将其影响降到最低。

互斥锁的使用

互斥锁提供互斥功能,生产者或消费者都可以拥有密钥(互斥锁)并继续工作。只要生产者填满缓冲区,用户就需要等待,反之亦然。在互斥锁中,始终只有一个线程可以使用整个缓冲区。

互斥锁的优点

据我观察,Mutex 的主要优点如下:

  • 互斥锁只是在进入其临界区之前获得的简单锁,然后释放它。
  • 由于在任何给定时间只有一个线程处于其临界区,因此不存在竞争条件,并且数据始终保持一致。

互斥锁的缺点

在我的实践中,我发现了 Mutex 的几个缺点。

  • 如果一个线程获得锁并进入休眠状态或被抢占,则另一个线程可能无法继续前进。这可能会导致饥饿。
  • 不能从与获取它的上下文不同的上下文中锁定或解锁它。
  • 每次只应允许一个线程进入临界区。
  • 正常执行可能会导致忙等待状态,浪费CPU时间。

之间的区别 Semaphore 和互斥

根据我使用它们的经验,以下是互斥锁和 Semaphore不同之处:

Semaphore 与互斥锁
Semaphore 与互斥锁
参数 Semaphore 互斥
机制 它是一种信号机制。 这是一种锁定机制。
数据类型 Semaphore 是一个整型变量。 互斥锁只是一个对象。
修改 等待和信号操作可以修改信号量。 它仅可由可能请求或释放资源的进程修改。
资源管理 如果没有空闲资源,则进程需要资源,并执行等待操作。它应该等待,直到信号量的计数大于 0。 如果被锁定,进程必须等待。进程应保存在队列中。仅当互斥锁解锁时才需要访问该队列。
Thread 您可以有多个程序线程。 互斥锁中可以有多个程序线程,但不能同时存在。
所有权 任何释放或获取资源的过程都可以改变该值。 对象锁仅由获得该锁的进程释放。
类型 有哪些 Semaphore 正在计数信号量和二进制信号量。 Mutex 没有子类型。
操作 Semaphore 使用wait()和signal()操作来修改值。 互斥对象被锁定或解锁。
资源占用 如果所有资源都在使用,则信号量被占用,请求资源的进程执行wait()操作并阻塞自身,直到信号量计数变为>1。 如果对象已被锁定,则请求资源的进程将等待,并且会被系统排队,直到锁被释放。

总结

根据我的经验,在互斥锁和信号量之间进行选择的关键是认识到它们的操作细微差别。 Semaphore非常适合复杂的同步,而互斥锁适合简单的互斥,从而确保简单环境中的资源安全。