假人的线程队列 [英] Thread queues for dummies

查看:77
本文介绍了假人的线程队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很常见的线程场景:

  • 我要完成100项相同的工作
  • 所有工作均独立于每个工作 其他
  • 我最多要处理 一次15个工作
  • 每项工作 完成后,将开始新工作 直到所有工作都完成

如果您假设每个工作都将在他完成时触发一个事件(我正在使用BackgroundWorker类),那么我可以想到几种方法来实现这一目标,但是我不确定正确"的含义是什么.解决的办法是.我希望你们中的一些大师能够为我指出正确的方向.

解决方案1::有一个 while(继续){Threading.Sleep(1000); } 循环到我的Main()函数中.当 A)没有要排队的作业且 B)所有排队的作业都已完成时,Job_Completed事件处理程序中的代码将设置continue = false.我在使用此解决方案之前和之后似乎都可以正常使用……对我来说似乎有点奇怪".

解决方案2:在我的Main()函数中使用Application.Run().同样,当 A)没有要排队的作业且 B)所有排队的作业都已完成时,Job_Completed事件处理程序中的代码将调用Application.Exit(). >

解决方案3::使用ThreadPool,将所有500-1000个请求排队,让它们一次运行10个(SetMaxThreads),然后以某种方式等待它们全部完成.

在所有这些解决方案中,基本思想是每次完成另一个作业时都会开始一个新作业,直到没有剩余的作业为止.因此,问题不仅在于等待现有作业完成,而且还要等待直到不再有任何待处理的作业开始.如果ThreadPool是正确的解决方案,那么等待ThreadPool完成所有排队项目的正确方法是什么?

我认为我最主要的困惑是我不完全了解如何从Main()函数中触发事件.显然他们知道,但是我只是从Windows消息循环的角度不了解它的机制.解决此问题的正确方法是什么?为什么?

解决方案

即使其他答案很不错,如果您想要另一个选择(您永远无法拥有足够的选择),那么如何解决这个问题呢?

只需将每个作业的数据放入FIFO堆栈中的结构中即可.

创建15个线程.

每个线程将从堆栈中获取下一个作业,将其弹出.

当线程完成处理时,获得下一个作业,如果堆栈为空,则线程死亡或只是休眠,等待.

唯一的复杂性(很容易解决)是将弹出窗口置于关键部分(同步读取/弹出).

I have what I assume is a pretty common threading scenario:

  • I have 100 identical jobs to complete
  • All jobs are independent of each other
  • I want to process a maximum of 15 jobs at a time
  • As each job completes, a new job will be started until all jobs have been completed

If you assume that each job will fire an event when he completes (I'm using the BackgroundWorker class), I can think of a couple of ways to pull this off, but I'm not sure what the "right" solution is. I was hoping some of you gurus out there could point me in the right direction.

SOLUTION 1: Have a while(continue) { Threading.Sleep(1000); } loop in my Main() function. The code in the Job_Completed event handler would set continue = false when A) no jobs remain to be queued and B) all queued jobs have completed. I have used this solution before and while it seems to work fine...it seems a little "odd" to me.

SOLUTION 2: Use Application.Run() in my Main() function. Similarly, the code in the Job_Completed event handler would call Application.Exit() when A) no jobs remain to be queued and B) all queued jobs have completed.

SOLUTION 3: Use a ThreadPool, queue up all 500-1000 requests, let them run 10 at a time (SetMaxThreads) and somehow wait for them all to complete.

In all of these solutions, the basic idea is that a new job would be started every time another job is completed, until there are no jobs left. So, the problem is not only waiting for existing jobs to complete, but also waiting until there are no longer any pending jobs to start. If ThreadPool is the right solution, what is the correct way to wait on the ThreadPool to complete all queued items?

I think my overriding confusion here is that I don't understand exactly HOW events are able to fire from within my Main() function. Apparently they do, I just don't understand the mechanics of it from a Windows message loop point-of-view. What is the correct way to solve this problem, and why?

解决方案

Even though the other answers are nice if you want another option (you can never have enough options), then how about this as an idea.

Just put the data for each job into a structure, which is in a FIFO stack.

Create 15 threads.

Each thread will get the next job from the stack, popping it off.

When a thread finishes the processing, get the next job, if the stack is empty the thread dies or just sleeps, waiting.

The only complexity, which is pretty simple to resolve, is having the popping be in a critical section (synchronize read/pop).

这篇关于假人的线程队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆