- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有 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/
当我使用 int event_idx = WaitHandle.WaitAny(ExportEvents.ToArray()); 如果事件在 WaitAny 函数调用之前处于信号状态,则 WaitAn
我有固定数量的“浏览器”,每个浏览器都不是线程安全的,因此必须在单个线程上使用。另一方面,我有一长串线程等待使用这些浏览器。我目前正在做的是有一个 AutoResetEvent 数组: public
我正在尝试编写一些代码来并行调用多个不同服务器的 Web 服务,因此 TPL 似乎是显而易见的选择。 我的 Web 服务调用中只有一个会返回我想要的结果,而其他所有调用都不会。我正在尝试找到一种有效地
我一直试图找到一种方法来异步检查以查看我使用videocapture拍摄的下一帧相机是否准备就绪。 我遇到了waitAny(),它被描述为“等待VideoCapture的就绪帧”。 在OpenCV文档
我在数组中有一系列任务。如果 Task 是“Good”,它会返回一个字符串。如果它是“坏”:它返回一个空值。 我希望能够并行运行所有任务,一旦第一个返回“好”,然后取消其他任务并获得“好”结果。 我现
我刚刚开始探索 TPL 并有一个设计问题。 我的场景:我有一个 URL 列表,每个 URL 都引用一个图像。我希望并行下载每个图像。下载至少一个图像后,我想执行一种方法来对下载的图像执行某些操作。该方
我对 WaitAll 和 WaitAny 有点困惑。我试图获得异常,但是当我执行 WaitAll 时它返回异常但是当使用 WaitAny 时什么都不返回。必要的是,如果任何任务完成工作完成。他们的任何
我正在创建一个系统,该系统会生成大量辅助任务,并且在我的应用程序的某个位置,我正在执行 Task.WaitAny 以检索第一个完成的任务。 我关心的是我可以向 WaitAny 发送多少任务,我知道 W
我发现了一些使用 Task.WaitAny 条件的代码。 Task[] tasks = new Task[3]; tasks[0] = Task.Run(() => { Thread.Sleep(20
我正在使用 Task.WaitAny 并传入正在运行的任务数组。如果有多个任务同时完成,我想知道如何捕获所有已完成任务的索引。 例如,我正在检索完成如下任务的索引:` int i = Task.Wai
int WaitAny(Task[] tasks, int millisecondsTimeout); 上述方法是否在超时后取消任务?看起来没有,但 C# 70-483 考试引用书说这个重载版本取消了
编辑:我什至想为暂时的精神错乱辩护,甚至问这个问题,但当时它是有道理的(见下面的编辑 2)。 对于 .NET 3.5 项目,我有两种类型的资源(R1 和 R2)需要检查其可用性。每种资源类型在任何时候
在这段代码中,您总是会得到相同的结果。不知道为什么这些任务的ID是1,3,4。 如果您在 int index = Task.WaitAny(tasks); 处放置一个断点并等待 2 秒,您将获得良好的
如何在超过 64 个句柄上实现 waitAny? 我有一个简单的问题,我有很多线程一直工作到数据结束,当线程是数据结束时,然后向线程发送信号,告诉线程我正在为空闲线程运行这个 waitAny 并给他下
如果我没记错的话,JoinBlock是 TPL 数据流的“WaitAll”:当您有一个 T1 和一个 T2 时,它会构建一个 Tuple并将其传递给下一个 block 。 是否有一个“ChoiceBl
以下代码是主/工作模式的实现。 Ibcast 用于终止所有工作人员,因为我们不知道程序开始时问题的大小。 MPI_Waitany() 用于等待 Irecv 获取新数据和 Ibcast 终止程序。 问题
我一直注意到对 WaitHandle.WaitAny 的调用会分配给它的 WaitHandle[] 的副本。从下面的链接或使用反射器可以看出: http://reflector.webtropy.co
我知道我的目标可以通过使用 Task.WhenAny() 来实现,但如果可以避免,我不会处理异步等待,以防止死锁。我有以下代码: try { Task.WaitAny(this.Tasks.To
我有 3 个线程,两个“ worker ”和一个“经理”。 “工作人员”线程在 EventWaitHandle 上等待,“经理”线程将在增加其计数器后向 EventWaitHandle 发出信号。这些
我正在将 C++ API 代码移植到 .NET 并研究函数调用 WaitHandle.WaitAny 作为 WaitForMultipleObjects< 的替代品 但在使用 .NET4 进行调试时,
我是一名优秀的程序员,十分优秀!