互斥锁与信号量 – 它们之间的区别

Mutex与Semaphore的关键区别

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

Difference between Mutex and Semaphore
Mutex与Semaphore的区别

在这里,我分析了Mutex和Semaphore之间的区别,并将全面评估它们的优缺点。

关于Mutex和Semaphore的常见事实

根据我的实践,以下是关于Mutex与Semaphore的一些常见事实

  • 只有一个任务可以获取互斥锁。因此,互斥锁具有所有权,只有所有者才能释放它。
  • 使用互斥锁和信号量的原因不同,也许因为它们的实现相似,互斥锁可以被视为二元信号量。
  • 一个广为人知的误解是,互斥锁和信号量几乎相同,唯一的区别是互斥锁能够计数到1,而信号量能够从0计数到N。
  • 二元信号量和互斥锁之间总是不确定。你可能会听说互斥锁是二元信号量,这是不正确的。

什么是Semaphore?

信号量仅仅是线程之间共享的非负变量。信号量是信号机制,等待信号量的线程可以被另一个线程信号。它使用两个原子操作,1)wait和2)signal进行进程同步

一个信号量根据其设置方式,允许或禁止对资源的访问。

Semaphore的用途

在单个缓冲区的情况下,我们可以将4 KB的缓冲区分成四个1 KB的缓冲区。信号量可以与这四个缓冲区关联。这允许用户和生产者同时处理不同的缓冲区。

Semaphore的优点

根据我的实践,以下是使用信号量的关键优点

  • 它允许多个线程访问临界区
  • 信号量是机器无关的。
  • 信号量在微内核的机器无关代码中实现。
  • 它们不允许多个进程进入临界区。
  • 由于信号量中存在忙等待调度,因此从不浪费进程时间和资源。
  • 它们是机器无关的,应该在微内核的机器无关代码中运行。
  • 它们允许灵活管理资源。

Semaphore的缺点

以下是我遇到的信号量的一些缺点。

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

什么是Mutex?

Mutex的完整形式是Mutual Exclusion Object(互斥对象)。它是一种特殊的二元信号量,用于控制对共享资源的访问。它包括优先级继承机制,以避免扩展的优先级反转问题。它允许当前优先级较高的任务被阻塞的时间尽可能短。然而,优先级继承并不能纠正优先级反转,只能最大限度地减小其影响。

Mutex的用途

互斥锁提供互斥,无论是生产者还是消费者都可以获得密钥(互斥锁)并继续工作。只要生产者填充缓冲区,用户就需要等待,反之亦然。在Mutex锁定中,所有时候,只有一个线程可以处理整个缓冲区。

Mutex的优点

根据我的观察,以下是Mutex的关键优势

  • 互斥锁只是简单的锁定,在进入其临界区之前获取,然后释放它。
  • 由于任何时候只有一个线程在其临界区中,因此没有竞态条件,数据始终保持一致。

Mutex的缺点

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

  • 如果一个线程获取了锁并进入休眠状态,或者它被抢占了,那么另一个线程可能无法继续前进。这可能导致饿死。
  • 它不能从获取它的上下文之外的上下文锁定或解锁。
  • 一次只允许一个线程进入临界区。
  • 正常的实现可能导致忙等待状态,浪费CPU时间。

Semaphore与Mutex的区别

根据我学习的经验,Mutex和Semaphore的区别如下:

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

结论

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