gpt4 book ai didi

c# - EventWaitHandle - WaitAny() 和 WaitOne() 之间的区别

转载 作者:可可西里 更新时间:2023-11-01 07:55:07 26 4
gpt4 key购买 nike

我有 3 个线程,两个“ worker ”和一个“经理”。 “工作人员”线程在 EventWaitHandle 上等待,“经理”线程将在增加其计数器后向 EventWaitHandle 发出信号。这些“工作”线程之间的唯一区别是一个使用 EventWaitHandle.WaitAny() 而另一个使用 EventWaitHandle.WaitOne()

代码如下:

class Program
{
static void Main(string[] args)
{
MultiThreadedJobs multyThreadedJobs = new MultiThreadedJobs();
multyThreadedJobs.Start();

Console.ReadLine();

multyThreadedJobs.Stop();
}
}

class MultiThreadedJobs : IDisposable
{
private EventWaitHandle syncEvent;
private EventWaitHandle[] syncEventsArray;

private Thread managerThread;
private Thread firstWorkerThread;
private Thread secondWorkerThread;

private volatile bool running = false;


public MultiThreadedJobs() // Ctor
{
syncEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "JobsSyncEvent");

syncEventsArray = new EventWaitHandle[1];
syncEventsArray[0] = syncEvent;

managerThread = new Thread(ManagerThreadMethod);
firstWorkerThread = new Thread(FirstWorkerThreadMethod);
secondWorkerThread = new Thread(SecondWorkerThreadMethod);
}

public void Start()
{
running = true;

managerThread.Start();
firstWorkerThread.Start();
secondWorkerThread.Start();
}

public void Stop()
{
running = false;
}

private void ManagerThreadMethod() // Manager Thread
{
while (running)
{
Thread.Sleep(1000);
syncEvent.Set();
}
}

private void FirstWorkerThreadMethod() // Worker Thread
{
int counter = 0;
while (running)
{
syncEvent.WaitOne();
counter++;
}
}

private void SecondWorkerThreadMethod() // Worker Thread
{
int counter = 0;
while (running)
{
EventWaitHandle.WaitAny(syncEventsArray);
counter++;
}
}

public void Dispose()
{
syncEvent.Close();
}
}

问题是,具有 EventWaitHandle.WaitAny() 的第二个工作线程总是捕获事件,并使第一个工作线程挨饿。而不是他们每个人大约 50/50%。

最佳答案

您正在寻找软件工程中一个非常常见问题的解决方案,Producer-consumer problem .链接的维基百科文章有很好的背景信息,特别是展示了如何以错误的方式进行操作。

您肯定在寻求错误的解决方案。 AutoResetEvent 过于简单。您已经发现了它的一个问题,它不提供公平性。它还有许多其他问题,特别是当生产者线程比消费者线程更快地生产作业时,它会遭受严重的线程竞争。

示例代码过于人为化,无法提供好的替代方案。低级锁定可以通过 ReaderWriterLock/Slim 类实现。 .NET 4 BlockingCollection 类是特别适合解决生产者/消费者问题的类。支持任意数量的生产者和消费者线程并提供节流以确保当消费者跟不上生产者时程序不会崩溃。您可以使用从生产者传递给消费者线程的假“ token ”来重写示例。 BlockingColletion<bool>完成工作。

关于c# - EventWaitHandle - WaitAny() 和 WaitOne() 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14732425/

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