我听说过这些与并发编程有关的词,但是锁、互斥量和信号量之间有什么区别呢?
当前回答
使用Linux变体上的C编程作为示例的基本情况。
锁:
•通常是一个非常简单的构造二进制在操作中锁定或解锁
•没有线程所有权、优先级、顺序等概念。
•通常是旋转锁,线程不断检查锁的可用性。
•通常依赖于原子操作,例如Test-and-set, compare-and-swap, fetch-and-add等。
•通常需要硬件支持原子操作。
文件锁:
•通常用于协调多个进程对文件的访问。
多个进程可以持有读锁,但是当任何一个进程持有写锁时,不允许其他进程获得读或写锁。
•示例:flock, fcntl等。
互斥:
互斥锁函数调用通常在内核空间中工作,并导致系统调用。
•它使用了所有权的概念。只有当前持有互斥锁的线程才能解锁它。
互斥不是递归的(异常:PTHREAD_MUTEX_RECURSIVE)。
•通常用于与条件变量关联,并作为参数传递给例如pthread_cond_signal, pthread_cond_wait等。
•一些UNIX系统允许多个进程使用互斥锁,尽管这可能不是在所有系统上强制执行。
信号量:
•这是一个内核维护的整数,其值不允许低于零。
•可用于同步进程。
信号量的值可以设置为大于1的值,在这种情况下,该值通常表示可用资源的数量。
•值限制为1和0的信号量称为二进制信号量。
其他回答
看一看John Kopplin的多线程教程。
在线程间同步一节中,他解释了事件、锁、互斥量、信号量和可等待计时器之间的区别
A mutex can be owned by only one thread at a time, enabling threads to coordinate mutually exclusive access to a shared resource Critical section objects provide synchronization similar to that provided by mutex objects, except that critical section objects can be used only by the threads of a single process Another difference between a mutex and a critical section is that if the critical section object is currently owned by another thread, EnterCriticalSection() waits indefinitely for ownership whereas WaitForSingleObject(), which is used with a mutex, allows you to specify a timeout A semaphore maintains a count between zero and some maximum value, limiting the number of threads that are simultaneously accessing a shared resource.
锁,互斥,信号量
这是一个普遍的愿景。细节取决于真正的语言实现
锁线程同步工具。当线程获得锁时,它就变成了一个能够执行代码块的单一线程。所有其他线程都被阻塞。只有拥有锁的线程才能解锁
互斥锁——互斥锁。这是一种锁。在某些语言中它是进程间机制,在某些语言中它是锁的同义词。例如,Java在synchronized和Java .util.concurrent.locks. lock中使用锁
信号量——允许多个线程访问共享资源。你可以发现互斥也可以通过信号量来实现。它是一个独立的对象,用于管理对共享资源的访问。您可以发现任何线程都可以发出信号并解除阻塞。它也被用于信号
[iOS锁,互斥量,信号量]
我的理解是互斥量只能在单个进程中使用,但可以跨多个线程使用,而信号量可以跨多个进程和它们对应的线程集使用。
此外,互斥是二进制的(它要么被锁定要么被解锁),而信号量有计数的概念,或者一个包含多个锁定和解锁请求的队列。
有人能证实我的解释吗?我说的是Linux环境,特别是使用内核2.6.32的Red Hat Enterprise Linux (RHEL)版本6。
支持所有权、最大进程共享锁数和临界区允许的最大进程/线程数是决定具有通用锁名的并发对象的名称/类型的三个主要因素。由于这些因素的值是二进制的(有两种状态),我们可以将它们总结为一个3*8的类真值表。
X(支持所有权?):no(0) / yes(1) Y(#共享进程):> 1(∞)/ 1 Z (#processes/threads in CA): > 1(∞)/ 1
X Y Z Name
--- --- --- ------------------------
0 ∞ ∞ Semaphore
0 ∞ 1 Binary Semaphore
0 1 ∞ SemaphoreSlim
0 1 1 Binary SemaphoreSlim(?)
1 ∞ ∞ Recursive-Mutex(?)
1 ∞ 1 Mutex
1 1 ∞ N/A(?)
1 1 1 Lock/Monitor
请随意编辑或展开这个表,我已经把它作为一个ascii表进行编辑:)
维基百科有一个关于信号量和互斥量区别的很好的章节:
A mutex is essentially the same thing as a binary semaphore and sometimes uses the same basic implementation. The differences between them are: Mutexes have a concept of an owner, which is the process that locked the mutex. Only the process that locked the mutex can unlock it. In contrast, a semaphore has no concept of an owner. Any process can unlock a semaphore. Unlike semaphores, mutexes provide priority inversion safety. Since the mutex knows its current owner, it is possible to promote the priority of the owner whenever a higher-priority task starts waiting on the mutex. Mutexes also provide deletion safety, where the process holding the mutex cannot be accidentally deleted. Semaphores do not provide this.
推荐文章
- Thread start()和Runnable run()有什么区别
- 在Swift中,什么相当于Objective-C的“@synchronized”?
- 是AsyncTask真的概念上有缺陷或我只是错过了一些东西?
- 信号量和监视器——有什么不同?
- AtomicInteger的实际用途
- 什么是协程?
- Std::lock_guard或Std::scoped_lock?
- Java中的Volatile vs Static
- 当Node.js内部仍然依赖线程时,它是如何固有地更快的?
- Volatile boolean vs AtomicBoolean
- 什么时候我需要在Java中使用AtomicBoolean ?
- ruby有真正的多线程吗?
- 为什么wait()必须总是在同步块中
- 并发、并行和异步方法之间的区别是什么?
- “Java并发实践”仍然有效吗?