使用 TPL 做一些“工作”

发布于 2024-11-02 07:03:29 字数 426 浏览 1 评论 0原文

我正在启动一个小“作业管理器”,它将执行一些“作业”对象,实现“IJob”方法。每个 IJob 都会返回一个潜在的新工作列表。

我的所有作业都存储在一个队列中,可以线程安全地访问该队列,当我完成作业时,我会向该队列添加新的查询作业。

我正在寻找如何将其与 TPL 并行化。

我有几个想法,但由于我的限制,它们都无效,这些限制是:

  • 我需要限制线程数(假设为 4 个),因为某些请求正在查询网站,该网站不允许超过4个同时请求(我想我可以用信号量来管理这个)
  • 我的作业列表会改变,所以我无法启动4个线程,将作业数量除以线程数量,并且每个线程都运行他的作业堆栈。
  • 也许有时候,如果我有 4 个线程,我就只剩下一个工作了,但我不能让其他线程停止,因为也许我要运行的最后一个工作会创造更多的工作。

非常感谢!

I'm starting a little "job manager", it will execute some "Job" object implement an "IJob" method. Every IJob finish by returning a potential list of new jobs.

All my jobs are stored in a Queue, which is accessed thread-safely, and when I finish a Job, I add to this queue new queried jobs.

I'm searching how to parallelize this with the TPL.

I've several ideas, but none of them are valid due to my constraints, which are:

  • I need to limit the number of thread(let's say to 4), because some request are quering a website, which doesn't allow more than 4 simultaneous requests(I think I can manage this with a semaphore)
  • My list of jobs will change, so I just cannot launch 4 thread, divide the number of jobs by the number of thread, and every thread runs his stack of job.
  • Maybe sometimes, if I've 4 thread, I've only one job more, but I can't let stop other thread, because maybe the last job I've to run will create a lot of more jobs.

Thank you very much!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

放肆 2024-11-09 07:03:29

这确实是动态任务并行。您的代码循环遍历您拥有的作业并执行每一项。每个作业都可以使用 addMethod 和并发队列将新作业添加到其中。

public static void ParallelWhileNotEmpty<T>(
  IEnumerable<T> initialValues, 
  Action<T, Action<T>> body)
{
  var opts = new ParallelOptions { MaxDegreeOfParallelism = 10 };
  var from = new ConcurrentQueue<T>(initialValues);  
  while (!from.IsEmpty)
  { 
    var to = new ConcurrentQueue<T>();
    Action<T> addMethod = to.Enqueue; 
    Parallel.ForEach(from, opts. body(v, addMethod));        
    from = to;
  }
}

这样,“循环”是开放式的,并且将持续到您用完工作为止。显然,您的真实应用程序会考虑重复的 URL,而不添加它们等。但这允许您的应用程序动态添加工作。您可以使用 ParallelOptions 来限制并发性,也可以编写调度程序。

有关动态任务并行性的详细信息,请参阅

http://msdn.microsoft.com/en -us/library/ff963551.aspx

有关示例的完整代码,请参阅

http://parallelpatterns.codeplex.com/SourceControl/changeset/view/54510#795590

以上两者都讨论了该主题的其他替代变体。

如果您希望自定义调度程序来限制并行度,请参阅 MSDN

http 上的示例: //msdn.microsoft.com/en-us/library/ee789351.aspx

This is really dynamic task parallelism. Your code loops through the Jobs you have and execute each one. Each job can add new jobs to the using an addMethod and a concurrent queue.

public static void ParallelWhileNotEmpty<T>(
  IEnumerable<T> initialValues, 
  Action<T, Action<T>> body)
{
  var opts = new ParallelOptions { MaxDegreeOfParallelism = 10 };
  var from = new ConcurrentQueue<T>(initialValues);  
  while (!from.IsEmpty)
  { 
    var to = new ConcurrentQueue<T>();
    Action<T> addMethod = to.Enqueue; 
    Parallel.ForEach(from, opts. body(v, addMethod));        
    from = to;
  }
}

This way the "loop" is open ended and will continue until you run out of work. Obviously your real application would account for duplicate URLs and not add them etc. But this allows your to app to dynamically add work. You can use the ParallelOptions to limit concurrency or you can write a scheduler.

For more information on dynamic task parallelism see

http://msdn.microsoft.com/en-us/library/ff963551.aspx

For the full code for the example see

http://parallelpatterns.codeplex.com/SourceControl/changeset/view/54510#795590

Both of the above discuss other alternative variations on this theme.

If you want a custom scheduler to limit the degree of parallelism see the example on MSDN

http://msdn.microsoft.com/en-us/library/ee789351.aspx

默嘫て 2024-11-09 07:03:29

您可以简单地使用 ParallelOptions.MaxDegreeOfParallelism 限制同时执行的并发任务数。

Reed Copsey 具有 他的博客上的示例

You could simply use ParallelOptions.MaxDegreeOfParallelism to limit how many concurrent tasks are executed at the same time.

Reed Copsey has an example on his blog.

屌丝范 2024-11-09 07:03:29

查看 Campbell、Johnson、Miller 和 Toub 编写的 Microsoft .NET 并行编程...特别是第 3 章的“通过 TPL 使用工作窃取算法的具有线程本地工作队列的全局队列”来处理负载平衡。

我用它作为我的一项设计的基础,它确实在性能上产生了巨大的差异。

Check out Parallel Programming with Microsoft .NET by Campbell, Johnson, Miller, and Toub ... specifically chapter 3's "Global queue with thread-local worker queues, via TPL, that employ a work stealing algorithm" to handle load balancing.

I use this as the basis for one of my designs and it really made a huge difference in performance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文