实现并行无限循环的最佳方法是什么?

时间:2022-08-16 19:34:07

I've gotten used to using Parallel.For() in .Net's parallel extensions as it's a simple way of parallelizing code without having to manually start and maintain threads (which can be fiddly). I'm now looking at an infinite loop (do something until I signal it to stop) that I wish to parallelize, there isn't an argument free Parallel.For() overload to do this so was wondering what the best approach here would be. In principle I could just do something like:

我已经习惯在.Net的并行扩展中使用Parallel.For(),因为它是一种并行化代码的简单方法,无需手动启动和维护线程(这可能是繁琐的)。我现在正在看一个无限循环(做一些事情,直到我发出信号停止),我希望并行化,没有一个参数可以*Parallel.For()重载这样做,所以想知道这里最好的方法是什么是。原则上我可以这样做:

Parallel.For(0, int.Max)

But I'm suspecting that might not be an expected/efficient pattern for the work partitioning logic to handle(?)

但我怀疑这可能不是工作分区逻辑处理的预期/有效模式(?)

Another option is something like:

另一种选择是:

for(;;)
{
    Parallel.For(0, 128, delegate()
    {
       // Do stuff.
    }
}

But that seems inelegant and may also result in inefficient work partitioning.

但这似乎不够优雅,也可能导致低效的工作分区。

Right now my instinct is to do this manually by creating and maintaining my own threads, but I would be interested in getting some feedback/opinions on this. Thanks.

现在我的直觉是通过创建和维护我自己的线程来手动执行此操作,但我有兴趣获得一些反馈/意见。谢谢。

=== UPDATE ===

===更新===

I'm using a simplified version of the code from the article in the accepted answer (I've removed the ParallelOptions parameter). Here's the code...

我在接受的答案中使用了文章中的代码的简化版本(我删除了ParallelOptions参数)。这是代码......

public class ParallelUtils
{
    public static void While(Func<bool> condition, Action body) 
    { 
        Parallel.ForEach(IterateUntilFalse(condition), ignored => body()); 
    }

    private static IEnumerable<bool> IterateUntilFalse(Func<bool> condition) 
    { 
        while (condition()) yield return true; 
    }
}

An example usage would be:

一个示例用法是:

Func<bool> whileCondFn = () => !_requestStopFlag;
ParallelUtils.While(whileCondFn, delegate()
{
    // Do stuff.


});

3 个解决方案

#1


8  

Stephen Toub has a post about Implementing Parallel While with Parallel.ForEach.

Stephen Toub有一篇关于使用Parallel.ForEach实现Parallels Parallel的帖子。

#2


2  

If you (really) want something infinite then you want it on as few cores a possible. None of the Parallel.For___ would be a good choice.

如果你(真的)想要一些无限的东西,那么你可以在尽可能少的内核上使用它。 Parallel.For ___都不是一个好选择。

What you (probably) need is a separate Thread or a Task created with the LongRunning option.

您(可能)需要的是使用LongRunning选项创建的单独Thread或Task。

And then make it wait on a semaphore, or as a last resort call Sleep() as often as possible.

然后让它等待信号量,或作为最后的手段尽可能多地调用Sleep()。

#3


1  

Considering that it's infinit calculus request, but you need to have some finit state on every "cycle", I would say that I would change a solution with an external for(;;) loop to execute a Parallel.ForEach(...) call on some event/state change. Like a Monitor signal, event notification, or something like that...

考虑到它是无限的微积分请求,但你需要在每个“循环”上都有一些finit状态,我会说我会改变一个带有外部for(;;)循环的解决方案来执行Parallel.ForEach(...)呼吁某些事件/状态改变。像监视器信号,事件通知或类似的东西......

#1


8  

Stephen Toub has a post about Implementing Parallel While with Parallel.ForEach.

Stephen Toub有一篇关于使用Parallel.ForEach实现Parallels Parallel的帖子。

#2


2  

If you (really) want something infinite then you want it on as few cores a possible. None of the Parallel.For___ would be a good choice.

如果你(真的)想要一些无限的东西,那么你可以在尽可能少的内核上使用它。 Parallel.For ___都不是一个好选择。

What you (probably) need is a separate Thread or a Task created with the LongRunning option.

您(可能)需要的是使用LongRunning选项创建的单独Thread或Task。

And then make it wait on a semaphore, or as a last resort call Sleep() as often as possible.

然后让它等待信号量,或作为最后的手段尽可能多地调用Sleep()。

#3


1  

Considering that it's infinit calculus request, but you need to have some finit state on every "cycle", I would say that I would change a solution with an external for(;;) loop to execute a Parallel.ForEach(...) call on some event/state change. Like a Monitor signal, event notification, or something like that...

考虑到它是无限的微积分请求,但你需要在每个“循环”上都有一些finit状态,我会说我会改变一个带有外部for(;;)循环的解决方案来执行Parallel.ForEach(...)呼吁某些事件/状态改变。像监视器信号,事件通知或类似的东西......