首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实现锁和阻塞线程

实现锁和阻塞线程
EN

Stack Overflow用户
提问于 2013-01-23 06:43:51
回答 1查看 300关注 1票数 0

如果一个线程试图获取一个锁,并且它被占用了,那么它应该进入睡眠状态,并保持睡眠状态,直到锁被释放。如果一个线程释放了一个锁(它被创建它的线程占用),它应该唤醒线程。

我的问题是,如果我们在锁地址上唤醒所有线程,还是在锁地址上唤醒单个线程(在锁释放之后),这会有区别吗?如果我们要唤醒一个线程,那么唤醒哪个线程是有意义的,第一个在锁地址上进入睡眠状态?

我可以看到唤醒一个线程的一些好处,因为如果我们唤醒所有线程,n-1可能会回到睡眠状态。但我不知道唤醒单个线程是否有缺点。

EN

回答 1

Stack Overflow用户

发布于 2013-01-23 13:09:34

我相信您混淆了windows锁(互斥、临界区)和锁监视器(在C#中,.Net监视器可以使用关键字C#作为进入/退出块的语法糖)。

Windows互斥锁和临界区只能进入和退出,即只有一个队列与它们关联。队列中的所有线程都在等待锁被释放,当这种情况发生时,队列中的下一个线程将控制锁并开始运行。所有这些都是自动发生的。当前持有锁的线程不参与此操作,它不能选择唤醒等待释放锁的一个或多个其他线程。

.NET的Monitor有两个队列:一个就绪队列和一个等待队列。

就绪队列的行为与Win32互斥锁或临界区队列完全相同,并使用Enter/Leave方法进行控制。

等待队列是使用Wait/Pulse/PulseAll方法控制的单独队列。这些方法只能由持有监视器的线程调用。当线程调用Wait时,它会释放Monitor并进入等待队列。然后,不同的线程可以调用Pulse来移动一个线程,或者调用Pulse All来将所有线程从等待队列移动到就绪队列(记住调用Pulse/PulseAll的线程持有监视器)。

从计算机科学的角度来看,监视器是同步线程所需的单一原语(信号量、事件、互斥锁、屏障等都可以用监视器来实现),从实用的角度来看,监视器作为互斥锁非常有用,并且适用于需要由两个线程在锁步中执行操作的情况。但是,在大多数情况下,使用事件时代码的可读性更好。

进一步阅读:

Wikipedia page about Monitors for the historic/computer science aspect

MSDN Monitor class

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14469440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档