gpt4 book ai didi

c# - WaitHandle.WaitAny 和信号量类

转载 作者:太空狗 更新时间:2023-10-29 21:37:14 32 4
gpt4 key购买 nike

编辑:我什至想为暂时的精神错乱辩护,甚至问这个问题,但当时它是有道理的(见下面的编辑 2)。

对于 .NET 3.5 项目,我有两种类型的资源(R1R2)需要检查其可用性。每种资源类型在任何时候都可以有(比方说)10 个实例。

当其中一种资源可用时,我的工作线程需要唤醒(线程数量可变)。在早期的实现中,只有一种资源类型,我使用信号量来检查可用性。

现在我需要等待跟踪资源可用性的两个单独的信号量(S1S2)。

WaitHandle[] waitHandles = new WaitHandle[] { s1, s2 };
int signalledHandle = WaitHandle.WaitAny(waitHandles);

switch (signalledHandle)
{
case 0:
// Do stuff
s1.Release();
case 1:
// Do stuff
s2.Release();
}

然而,这有一个问题。来自 WaitAny 的 MSDN 文档:

If more than one object becomes signaled during the call, the return value is the array index of the signaled object with the smallest index value of all the signaled objects.

这表明我可能在调用 WaitAny 后将我的两个信号量计数都减少了 1。因为 signalledHandle 将指示 s1 已发出信号,所以我将开始使用资源 R1,并在完成后释放它。但是,由于我不知道 S2 是否收到信号,因此此资源的可用性计数现在可能已关闭。如果这种情况发生 10 次,我的信号量将永久“空”,资源 R2 将不再被使用。

处理此问题的最佳方法是什么?我是否应该从使用两个信号量切换到简单的计数器和一个 AutoResetEvent 以在任一计数器更改时发出信号?我是否缺少一些更优雅的方法?

编辑 1:
根据 Ravadre 的说法,只有一个信号量会在 WaitAny 之后实际改变。稍微修改他的示例似乎证实了这一点,但有没有人可以指出一些官方文档来说明这一点?

编辑 2:
我在回家的路上一直在想这个问题。直到那时我才意识到 WaitAny 必须是真的才有用。这个问题并不局限于信号量,而是任何类型的同步对象,这使得 WaitAny 实际上毫无用处。

最佳答案

如果我正确理解你的问题,我认为你的解决方案完全没问题,你只是在解释 msdn 引用。当调用 WaitHandle.WaitAny() 时,您将获得最低的索引,但您将只锁定一个 waitHandle(在本例中为信号量),检查示例代码:


Semaphore s1 = new Semaphore(1, 2);
Semaphore s2 = new Semaphore(1, 2);

WaitHandle[] handles = new WaitHandle[] { s1, s2 };

int x = WaitHandle.WaitAny(handles);

int prevS1 = s1.Release();
int prevS2 = s2.Release();

在这种情况下,prevS1 将等于 0,因为信号量 s1“被等待”,所以它的计数器已减为 0,而 prevS2 将等于 1,因为它的状态自实例化以来没有改变(Release() 方法返回释放前的计数器,因此返回 1 表示“它是 1,现在是2”)。

您可能想查看的另一个资源:http://www.albahari.com/threading/part2.aspx#_Wait_Handles .虽然它不是“官方”来源,但我认为没有理由认为它不可靠。

关于c# - WaitHandle.WaitAny 和信号量类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1300094/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com