个性化阅读
专注于IT技术分析

互斥与信号量(Mutex和Semaphore)有什么区别?

Mutex和Semaphore有什么区别?何时使用互斥锁以及何时使用信号量?

设计/开发智能应用程序需要对操作系统概念有具体的了解。我们的目标是教育读者这些概念, 并向其他专家极客学习。

按照操作系统术语, 互斥量和信号量是提供同步服务的内核资源(也称为同步原语)。为什么我们需要这样的同步原语?会不会只有一个?要回答这些问题, 我们需要了解几个关键字。请阅读以下文章原子性和关键部分。我们将通过示例进行说明, 以更好地理解这些概念, 而不是遵循通常的OS文字描述。

生产者-消费者问题:

注意, 该内容是概括性的说明。实际细节随实现方式而变化。

考虑标准的生产者-消费者问题。假设我们有一个4096字节长的缓冲区。生产者线程收集数据并将其写入缓冲区。使用者线程处理从缓冲区收集的数据。目的是, 两个线程不应同时运行。

使用Mutex:

互斥锁提供互斥, 生产者或消费者都可以拥有密钥(互斥锁)并继续其工作。只要缓冲区由生产者填充, 消费者就需要等待, 反之亦然。

在任何时候, 只有一个线程可以与整个缓冲。可以使用信号量来概括该概念。

使用信号量:

信号量是广义互斥量。代替单个缓冲区, 我们可以将4 KB缓冲区拆分为四个1 KB缓冲区(相同的资源)。信号量可以与这四个缓冲区关联。消费者和生产者可以同时在不同的缓冲区上工作。

误解:

两者之间存在歧义二进制信号量和互斥体。我们可能碰到互斥体是二进制信号量。但是他们不是!互斥量和信号量的目的是不同的。可能是由于互斥量在实现上的相似性而被称为二进制信号量。

严格来说, 互斥是锁紧机构用于同步对资源的访问。只有一个任务(可以是基于OS抽象的线程或进程)可以获取互斥量。这意味着存在与互斥锁关联的所有权, 并且只有所有者才能释放锁(互斥锁)。

信号量是信号机制(“我做完了, 你可以继续进行下去”)。例如, 如果你正在手机上收听歌曲(假设它是一项任务), 并且你的朋友同时打给你, 则会触发中断, 中断服务程序(ISR)会在该中断信号通知呼叫处理任务唤醒。

一般的问题:

1.一个线程可以获取多个锁(Mutex)吗?

是的, 一个线程可能需要多个资源, 因此需要锁。如果没有可用的锁, 线程将在锁上等待(阻止)。

2.互斥锁可以锁定多次吗?

互斥锁是一个锁。仅一个状态(锁定/解锁)与之关联。但是, 递归互斥可以被多次锁定(POSIX投诉系统), 其中一个计数与之关联, 但仅保留一个状态(锁定/解锁)。程序员必须将互斥体解锁的次数是被锁定的次数。

3.如果非递归互斥体被多次锁定, 会发生什么情况。

僵局。如果已经锁定了互斥锁的线程再次尝试锁定该互斥锁, 它将进入该互斥锁的等待列表, 这将导致死锁。这是因为没有其他线程可以解锁互斥锁。操作系统实现者可以谨慎地识别互斥对象的所有者, 如果互斥对象已被同一线程锁定, 则返回该互斥对象以防止死锁。

4.二进制信号量和互斥量是否相同?

否。我们建议将它们分开对待, 因为它解释了信号传递与锁定机制。但是二进制信号量可能会遇到与互斥相关的相同关键问题(例如优先级倒置)。我们将在后面的文章中介绍这些内容。

程序员更喜欢使用互斥锁, 而不是创建具有计数1的信号灯。

5.什么是互斥和关键部分?

某些操作系统使用相同的词关键部分在API中。通常, 由于与互斥锁相关联的保护协议, 其操作成本很高。最后, 互斥的目标是原子访问。还有其他方法可以实现原子访问, 例如禁用中断可能会更快, 但会破坏响应能力。备用API使用了禁用中断。

6.什么是事件?

互斥量, 信号量, 事件, 关键部分等的语义是相同的。全部都是同步原语。根据使用它们的成本, 它们是不同的。我们应该查阅操作系统文档以获取确切的详细信息。

7.我们可以在中断服务程序中获取互斥/信号量吗?

一个ISR将在当前运行线程的上下文中异步运行。它是不建议查询(阻止调用)ISR中的同步原语的可用性。 ISR的含义很短, 对互斥量/信号量的调用可能会阻止当前正在运行的线程。但是, ISR可以发信号通知信号或解锁互斥锁。

8.当互斥体/信号量不可用时, 我们所说的”线程阻塞”是什么意思?

每个同步原语都有一个与其关联的等待列表。当资源不可用时, 请求线程将从处理器的运行列表移至同步原语的等待列表。资源可用时, 等待列表中优先级较高的线程将获取资源(更确切地说, 它取决于调度策略)。

9.当资源不可用时, 线程是否必须始终阻塞?

不必要。如果设计确定‘资源不可用时该怎么办‘, 线程可以承担这项工作(另一个代码分支)。为了支持应用程序要求, 操作系统提供了非阻塞API。

例如POSIX pthread_mutex_trylock()API。当互斥锁不可用时, 该函数将立即返回, 而API pthread_mutex_lock()会阻塞线程, 直到资源可用为止。

参考文献:

http://www.netrino.com/node/202

http://doc.trolltech.com/4.7/qsemaphore.html

还将互斥量/信号量与Peterson算法和Dekker算法进行比较。一个很好的参考是并发的艺术书。还可以在Qt文档中探索读者锁和作家锁。

练习:

实现一个程序, 该程序在同一会话中执行多次时, 将打印一条消息”实例正在运行”。例如, 如果我们在Windows中观察Word应用程序或Adobe Reader, 则在任务管理器中只能看到一个实例。如何执行呢?

如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。

赞(0)
未经允许不得转载:srcmini » 互斥与信号量(Mutex和Semaphore)有什么区别?

评论 抢沙发

评论前必须登录!