WaitHandle.WaitAny和Semaphore类WaitHandle、WaitAny、Semaphore

由网友(沒話)分享简介:编辑:我想申辩临时精神错乱甚至问这个问题,但它是有意义的时候(见下文编辑2)I'd like to plead temporary insanity for even asking this question, but it made sense at the time (see edit 2 below).对于....

编辑:我想申辩临时精神错乱甚至问这个问题,但它是有意义的时候(见下文编辑2)

I'd like to plead temporary insanity for even asking this question, but it made sense at the time (see edit 2 below).

对于.NET 3.5的项目,我有两种类型的资源( R1 和 R2 的),我需要检查的可用性。每个资源类型可以有(比方说)10实例随时

For a .NET 3.5 project, I have two types of resources (R1 and R2) that I need to check the availability of. Each resource type can have (say) 10 instances at any time.

在任何类型的资源之一可用时,我的工作线程需要唤醒(有一个可变数目的线程)。在早期的实现,只有一种资源类型,这是我用一个信号量来查询。

When one of either types of resources becomes available, my worker thread needs to wake up (there is a variable number of threads). In an earlier implementation, there was only one resource type, for which I used a Semaphore to check availability.

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

Now I need to wait on two separate Semaphores (S1 and S2) that track availability of the resources.

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();
}

有一个问题与此但是。从MSDN文档了WaitAny

如果一个以上的对象成为   通话,返回过程中信号   值的数组索引   具有最小信号通知对象   所有的信号指标值   对象。

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 的将不会在所有的再使用。

This suggests that it's possible that I decreased both my Semaphore counts by 1 after calling WaitAny. Because signalledHandle will indicate that s1 was signalled, I will start using resource R1, and release it when I'm done. However, since I do not know if S2 was signalled or not, the availability count on this resource might now be off. If this happens 10 times, my Semaphore will be permanently 'empty' and resource R2 will not be used at all anymore.

什么是对付它的最好方法?我应该使用两个信号来简单的计数器和一个的AutoResetEvent信号时,无论计数器改变切换?我缺少一些更好的方法?

What is the best way to deal with this? Should I switch from using two semaphores to simple counters and an AutoResetEvent to signal when either counter is changed? Am I missing some more elegant approach?

修改1: 据Ravadre,只有一个信号量实际上将在了WaitAny 改变。稍微改变他的例子似乎也印证了这一点,但是否有任何人可以点我的一些片正式文件,指定呢?

Edit 1: According to Ravadre, only one of the Semaphores will actually be altered after WaitAny. Slightly modifying his example seems to confirm this, but is there anyone that can point me to some piece of official documentation that specifies this?

编辑2: 我在想这个在回家的路上。只有这样,我才知道这一定是如此了WaitAny 来才有用。这个问题不会受限于信号量,但几乎所有类型的同步对象,使了WaitAny 毫无实际用处的。

Edit 2: I was thinking about this on my way home. Only then I realized that this must be true for WaitAny to be of any use. This problem would not be restricted to Semaphores, but just about any type of synchronization object, making WaitAny practically useless.

推荐答案

如果我正确理解你的问题,我认为您的解决方案是完全确定,你只是国米preting msdn的报价。当调用 WaitHandle.WaitAny()您将得到最低的指数,但你会锁定只有一个WaitHandle的(信号在这种情况下),检查该样品code:

If I understand your problem correctly, I think that your solution is perfectly ok, and you are just over interpreting the msdn quote. When calling WaitHandle.WaitAny() you will get the lowest index, but you will lock on only one waitHandle (semaphore in this case), check this sample code:


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,因为它的状态并没有改变,因为它的实例(发行()方法返回释放前的柜台,所以返回1表示这是1,现在是2)。

In this scenario, prevS1 will be equal to 0, because semaphore s1 "was waited on", so it's counter has been reduced to 0, whereas prevS2 will be equal to 1, because it's state hasn't changed since it's instantiation (Release() method returns the counter before releasing, so returning 1 means "it was 1, now it's 2").

,你可能想看看另一种资源: HTTP://www.albahari。 COM /线程/ part2.aspx#_Wait_Handles 。尽管这不是一个官方的来源,我认为没有理由觉得不可靠的。

Another resource that you might want to look at : http://www.albahari.com/threading/part2.aspx#_Wait_Handles. Although it's not an "official " source, I think there's no reason to find it not reliable.

阅读全文

相关推荐

最新文章