我听说过这些与并发编程有关的词,但是锁、互斥量和信号量之间有什么区别呢?
当前回答
我的理解是互斥量只能在单个进程中使用,但可以跨多个线程使用,而信号量可以跨多个进程和它们对应的线程集使用。
此外,互斥是二进制的(它要么被锁定要么被解锁),而信号量有计数的概念,或者一个包含多个锁定和解锁请求的队列。
有人能证实我的解释吗?我说的是Linux环境,特别是使用内核2.6.32的Red Hat Enterprise Linux (RHEL)版本6。
其他回答
维基百科有一个关于信号量和互斥量区别的很好的章节:
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.
锁只允许一个线程进入被锁的部分,并且锁不与任何其他进程共享。
互斥锁与锁相同,但它可以是系统范围的(由多个进程共享)。
信号量的作用与互斥量相同,但允许x个线程进入,这可以用于限制同时运行的cpu、io或ram密集型任务的数量。
关于互斥量和信号量区别的更详细的文章请阅读这里。
您还可以使用读/写锁,在任何给定时间允许无限数量的读取器或1个写入器。
这些描述是从。net的角度出发的,对于所有操作系统/语言可能不是100%准确。
支持所有权、最大进程共享锁数和临界区允许的最大进程/线程数是决定具有通用锁名的并发对象的名称/类型的三个主要因素。由于这些因素的值是二进制的(有两种状态),我们可以将它们总结为一个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表进行编辑:)
关于这些词有很多误解。
这是之前的一篇文章(https://stackoverflow.com/a/24582076/3163691),非常适合这里:
1)临界区(Critical Section) =用户对象,用于允许在一个进程中执行多个活动线程中的一个活动线程。其他未被选中的线程(@获取该对象)将进入睡眠状态。
[没有进程间能力,非常基本的对象]。
2)互斥信号量(Mutex Semaphore,又名Mutex)=内核对象,用于允许在不同的进程中,只执行一个活动线程。其他未被选中的线程(@获取该对象)将进入睡眠状态。该对象支持线程所有权、线程终止通知、递归(同一个线程的多个“acquire”调用)和“优先级反转避免”。
[进程间能力,使用非常安全,一种'高级'同步对象]。
3)计数信号量(又名Semaphore)=内核对象,用于允许来自许多其他线程的一组活动线程的执行。其他未被选中的线程(@获取该对象)将进入睡眠状态。
[然而,进程间功能使用起来不太安全,因为它缺乏以下'互斥'属性:线程终止通知,递归?,“优先倒置规避”?等)。
4)现在,说到“自旋锁”,首先是一些定义:
关键区域(Critical Region):由两个或多个进程共享的内存区域。
Lock=其值允许或拒绝进入“关键区域”的变量。(它可以被实现为一个简单的“布尔标志”)。
忙碌等待=持续测试一个变量,直到某个值出现。
最后:
自旋锁(Spinlock)=一种使用忙等待的锁。(锁的获取是通过xchg或类似的原子操作完成的)。
没有线程睡眠,主要只在内核级使用。对于用户级别代码无效]。
作为最后的评论,我不确定,但我可以跟你打赌,上面的前3个同步对象(#1,#2和#3)使用这个简单的野兽(#4)作为它们实现的一部分。
祝你有愉快的一天!
引用:
-《嵌入式系统的实时概念》,作者:Qing Li和Caroline Yao (CMP Books)。
——安德鲁·塔南鲍姆(皮尔逊教育国际)的《现代操作系统》(第三期)。
-为微软Windows编程应用程序(第4)由Jeffrey Richter(微软编程系列)。
另外,你可以看看看看: https://stackoverflow.com/a/24586803/3163691
我的理解是互斥量只能在单个进程中使用,但可以跨多个线程使用,而信号量可以跨多个进程和它们对应的线程集使用。
此外,互斥是二进制的(它要么被锁定要么被解锁),而信号量有计数的概念,或者一个包含多个锁定和解锁请求的队列。
有人能证实我的解释吗?我说的是Linux环境,特别是使用内核2.6.32的Red Hat Enterprise Linux (RHEL)版本6。
推荐文章
- 为什么pthreads的条件变量函数需要互斥?
- 并发HashSet<T>在。net框架?
- 为什么这个Java程序会终止,尽管它显然不应该(也没有)终止?
- 同步vs锁定
- NOLOCK提示在SELECT语句中的作用
- LMAX的干扰模式是如何工作的?
- 互斥实例/教程?
- 假唤醒在Java中真的发生了吗?
- 线和纤维的区别是什么?
- Java同步方法锁定对象,或方法?
- Haskell对Node.js的响应是什么?
- Thread start()和Runnable run()有什么区别
- 在Swift中,什么相当于Objective-C的“@synchronized”?
- 是AsyncTask真的概念上有缺陷或我只是错过了一些东西?
- 信号量和监视器——有什么不同?