- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个简单的生产者/消费者场景,其中只有一个项目被生产/消费。此外,生产者在继续之前等待工作线程完成。我意识到这种方式避免了多线程的全部意义,但请假设它确实需要这样(:
这段代码无法编译,但我希望你明白了:
// m_data is initially null
// This could be called by any number of producer threads simultaneously
void SetData(object foo)
{
lock(x) // Line A
{
assert(m_data == null);
m_data = foo;
Monitor.Pulse(x) // Line B
while(m_data != null)
Monitor.Wait(x) // Line C
}
}
// This is only ever called by a single worker thread
void UseData()
{
lock(x) // Line D
{
while(m_data == null)
Monitor.Wait(x) // Line E
// here, do something with m_data
m_data = null;
Monitor.Pulse(x) // Line F
}
}
这是我不确定的情况:
假设许多线程使用不同的输入调用 SetData()。他们中只有一个会进入锁内,其余的将被挡在 A 线上。假设进入锁内的那个设置了 m_data 并进入了 C 行。
问题:C 行的 Wait() 是否允许 A 行的另一个线程在工作线程到达之前获取锁并覆盖 m_data?
假设这没有发生,工作线程处理原始的 m_data,并最终到达 F 行,当 Pulse() 关闭时会发生什么?
是否只有在C行等待的线程才能拿到锁?或者它会与所有其他在 A 线上等待的线程竞争吗?
本质上,我想知道 Pulse()/Wait() 是否专门“在幕后”相互通信,或者它们是否与 lock() 处于同一级别。
这些问题的解决方案(如果存在的话)当然是显而易见的 - 只需在 SetData() 周围加上另一个锁 - 比如 lock(y)。我只是很好奇这是否是一个问题。
最佳答案
不能保证消费者会在另一个生产者之前进入等待或就绪队列。
C# 和 Java 风格的监视器在 Wikipedia, under "Implicit condition monitors" 中有描述。 .
对 Monitor
中发生的事情的一个很好的概述(取自 this 优秀网站):
"Could the Wait() on Line C allow another thread at Line A to obtain the lock and overwrite m_data before the worker thread even gets to it?"
假设 SetData()
被两个生产者线程 P1 和 P2 调用。
消费者线程 C1 也已启动。
P1、P2和C1都进入就绪队列。
P1先获取锁。
等待队列为空,B 行
上的Pulse()
无效。
P1在C行
等待,所以它被放入等待队列。
就绪队列中的下一个线程获取锁。
它同样可以是 P2 或 C1 - 在第一种情况下,断言失败。
你有一个竞争条件。
"Supposing that doesn't happen, and the worker thread processes the original m_data, and eventually makes its way to Line F, what happens when that Pulse() goes off?"
它将一个服务员从等待队列移动到就绪队列。
锁由发出 Pulse()
的线程持有。
在脉冲线程释放锁后,通知线程将有机会获取锁(就绪队列中可能已经有其他线程)。
来自 MSDN, Monitor.Pulse() :
“当前拥有指定对象锁的线程调用此方法以向排队的下一个线程发出锁信号。在接收到脉冲后,等待线程被移至就绪队列。当调用 Pulse 的线程释放锁,就绪队列中的下一个线程(不一定是被脉冲的线程)获取锁。”
"Will only the thread waiting on Line C be able to get the lock? Or will it be competing with all the other threads waiting on Line A as well?"
就绪队列中的所有线程“竞争”下一个锁。
他们是直接到达那里还是通过 Pulse()
从等待队列到达那里并不重要。
“队列”可以通过其他方式实现。 (不是队列这样的数据结构)。
这样,Monitor
实现可能无法保证公平性 - 但可能具有更高的整体吞吐量/性能。
关于c# - 这种对 Monitor.Wait/Pulse 的使用是否存在竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2631658/
我正在尝试通过连接到我的 linkedin 应用程序将我的博客集成到 Linkedin Pulse。我发现发布到 API /v1/people/~/shares 会分享我的更新,但我不知道如何在 Pu
我正在尝试在我的 GUI 系统中的两个线程之间进行同步。 系统主要任务是初始化两个同步对象并运行两个线程: private FetcherAPI fetcherAPI { get; set; } pr
我有这个生产者/消费者代码: 主要内容: static void Main() { using(PCQueue q = new PCQueue(2)) { for(in
我有一个类,它应该是线程安全的。我最好想用一个同步对象来管理线程安全,以避免复杂的思维破坏,因为所有方法都会改变对象状态变量。因此,我在该对象上用 lock 语句包装方法体。在某些情况下,需要释放锁一
如何制作一个可滚动的Pulse-like导航栏(区域由矩形标记)?有人可以给我举个例子吗? 谢谢吕赖尼 最佳答案 其实很简单。只是嵌套 ScrollView 。外面的覆盖整个屏幕,只允许垂直滚动。 每
如何使 div/input 闪烁或“脉冲”?例如,假设表单字段输入了无效值? 最佳答案 使用 CSS3 类似 on this page ,您可以将脉冲效果添加到名为 error 的类中: @-webk
我遇到了一个问题,我将其简化为这个最小的测试用例,但我仍然不明白为什么它不能正常工作。这里的代码很简单:父线程获取一个锁,然后启动一个子线程,接下来通过启动 await 来释放锁。然后被锁定在同一个锁
我只是想确保我了解这里的内容。如果我使用 Monitor.Enter 或 lock 获得锁定,我是否需要在释放锁定之前调用 Pulse? Monitor.Enter Monitor.Pulse //
他们似乎都实现了相同的目的。我什么时候可以选择一个? 最佳答案 当您的线程正在等待多个事件之一或全部在做某事时,请使用事件。 如果要通过限制可以访问多少线程来限制对数据结构的访问,请使用监视器。 监视
我下载了Sound.Pulse.Simple并复制并粘贴示例程序: main=do s Fractional (GHC.Real.Ratio a) -- Defined in `GHC.R
我想重现active noise-control的效果使用普通耳机和 Linux 计算机的耳机,以便实时静音任何环境噪音(不仅仅是从背景噪音中清除声音输入)。 计划是通过 Alsa/Pulseaudi
我对网络开发知之甚少。 我正在尝试将代码添加到 linkedin 帖子,我尝试了 github Gist 但它不起作用。 有办法还是根本不可能? 最佳答案 似乎仍然(截至 2017 年 11 月 27
我创建了一个脉冲动画,它在 map 上占据一个位置,并持续发出一个脉冲(圆圈)。这按预期工作。但是,我希望脉冲淡出,离点越远。关于如何实现最佳效果有什么想法吗? 动画如下: mCircle =
我想知道如何像应用程序Pulse一样通过表格显示图像。在 iPhone 上。我使用了 UIScrollView 但它并没有太大帮助。它仅以类似数组的方式显示图像,但您无法产生事件或单击图像。 生成 P
我正在尝试优化与 Monitor.Wait 和 Monitor.Pulse 方法类似(基本功能)的异步版本。我们的想法是通过异步方法使用它。 要求:1) 我有一个任务正在运行,它负责等待有人给我的显示
http://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystified Queues:
根据 MSDN , Monitor.Wait(): Releases the lock on an object and blocks the current thread until it reac
我正在尝试编写一个基本的卷应用程序。由于我是用 Ruby 编写的,因此我不想扩展 C 库或使用 ffi ,而是尝试使用 ruby-dbus 编写它,我使用 Address 获得了 /org/pulse
有没有人在基于 Ubuntu 的 Linux 发行版上成功使用 Juniper Junos 脉冲客户端。 我想知道是否有任何可靠的基于浏览器的 VPN 客户端可以用作替代方案 谢谢 最佳答案 Alex
Delphi Docwiki 解释说 Pulse通知等待队列中的下一个线程,一旦调用线程释放该对象,它将能够锁定指定的对象。 PulseAll向等待队列中的所有线程发出信号。 我found这段代码在线
我是一名优秀的程序员,十分优秀!