smw*_*dia -1 c# queue multithreading
根据MSDN:
Monitor 类由静态(在 C# 中)或共享(在 Visual Basic 中)方法组成,这些方法对控制对关键部分的访问的对象进行操作。为每个同步对象维护以下信息:
对当前持有锁的线程的引用。
对就绪队列的引用,其中包含准备获取锁的线程。
对等待队列的引用,其中包含正在等待锁定对象状态更改通知的线程。
在这个线程中,两个队列引起了一些微妙的问题。
我认为上述线程中问题的根本原因是有 2 个队列。如果只有一个队列,则无论何时Monitor.Pulse(),都只能调度该队列中的一个线程来运行。没有办法让多个线程同时处于就绪状态。所以这个问题永远不应该发生。
那么为什么a要Monitor保留2个队列呢?
我认为你误解了那个帖子。该问题不是由 Monitor 引起的,而是由该 OP 的 Queue 类中的真正逻辑错误引起的。
删除是一种熟悉的模式,它应该使用 awhile而不是if:
lock (q)
{
// if (q.Count == 0)
while (q.Count == 0)
{
Monitor.Wait(q);
}
... // use it, we are now sure that q.Count > 0
}
Run Code Online (Sandbox Code Playgroud)
然后您可能需要一种额外的方式(CancellationToken)来结束整个过程。
一个Monitor可以有2种等待线程,实现者选择使用2个队列。使用 1 个队列似乎是可能的,但这不会改变任何事情。它仍然只允许在任何时候运行 1 个线程,所以此时您的理解不知何故出了问题。
正在发生的情况是排队线程可以具有以下两种状态之一:
lock(q)并且锁已被占用时,它会排队等待就绪Wait(q)它会排队等待并需要 Pulse() 来唤醒当没有线程等待脉冲时,脉冲/等待机制有点不可靠。一般来说,您不能依靠 Pulse/Wait 来进行精确的簿记。而Monitor的合约不包含公平性
| 归档时间: |
|
| 查看次数: |
362 次 |
| 最近记录: |