什么是信号量?
信号量是一个非负变量, 并且在线程之间共享。信号量是一种信号机制,一个线程正在等待信号量可以由另一个线程发出。它使用两个原子操作,1)wait
和 2)signal
实现线程同步。
信号量实现允许或不允许访问资源,这取决于它的设置方式。
什么是互斥锁?
互斥的完整形式是互斥对象。它是一种特殊类型的二进制信号,用于控制对共享资源的访问。它包含了一个优先级继承机制来避免扩展优先级反转问题。它允许当前优先级较高的任务在尽可能短的时间内保持在阻塞状态。然而,优先级继承并不能解决优先级反转问题,只能最小化其影响。
主要区别:
互斥锁是一种锁机制,信号量是一种信号机制
互斥锁是一个对象,信号量是一个整数
互斥锁没有子类型,信号量有两种子类型,计数信号量和二进制信号量
信号量支持wait和signal操作修改,而互斥锁仅能由可能请求或释放资源的进程修改
信号量的值使用wait()
和signal()
这两个方法修改,而互斥锁使用lock和unlock来操作。
使用信号量
在单个缓冲区的情况下,我们可以将4KB的缓冲区分成四个1KB的缓冲区。信号量可以与这四个缓冲区相关联。这允许用户和生产者同时在不同的缓冲区上工作。
使用互斥锁
互斥锁提供了互斥的功能,不管是生产者还是消费者,都可以持有锁,持有锁的一方可以继续工作,另一方就要等待,在同一时间,只有一个线程可以处理整个缓冲区。
关于互斥和信号量的常见事实
- 只有一个任务可以获取到互斥锁,互斥锁有所有权,只有持有锁的任务才能释放互斥锁。
- 使用互斥锁和信号量的场景是不同的,但是因为实现方式有相似之处,互斥锁也被称为二进制信号量
- 一个众所周知的错误:互斥量和信号量几乎相同,唯一的区别是互斥量能够计数到1,而信号量能够从0计数到N
- 二进制信号量和互斥量之间总是存在不确定性。你可能听说互斥锁是一个二进制信号量,这是不正确的
信号量的优点
- 允许多个线程访问临界区
- 信号量是独立于机器的(因为它们是在内核服务中实现的)
- 不允许多个进程进入临界区。
- 信号量有忙等状态,因为不会浪费时间和资源
互斥锁的优点
- 互斥锁只是简单的锁,在进入临界区是持有它,离开时释放
- 由于在任何给定时间只有一个线程处于临界区内,因此不存在数据竞争,可以始终保持数据一致性
信号量的缺点
- 信号量的最大限制之一是优先级反转问题
- 操作系统必须跟踪所有信号量的调用
- 为了避免信号量中的死锁,
wait
和signal
操作需要以正确的顺序执行 - 信号量编程是一种复杂的方法,因此有可能无法实现互斥的效果
- 它也不是可以大规模使用的实用方法,因为它们的使用会破坏模块化
- 程序员使用信号量更容易出错,容易出现死锁
互斥锁的缺点
- 如果一个持有锁的线程休眠或者被强占了CPU,其他线程就没办法继续执行了
- 一次只能允许一个线程访问临界区
- 正常实现可能会导致忙等待状态,浪费CPU时间
网友评论