我可以在 Parallel.For 循环中使用相同的函数委托吗

Posted

技术标签:

【中文标题】我可以在 Parallel.For 循环中使用相同的函数委托吗【英文标题】:Can I use the same function delegate in a Parallel.For Loop 【发布时间】:2014-09-16 07:54:51 【问题描述】:

是否可以在 Parallel.For 循环中使用相同的函数委托,还是在死锁中运行。

这意味着我想做这样的事情:

    public Execute(float[] input, Func<float, int, bool> WorkOnIt)
    
        Parallel.For(0, input.GetLength(0), i =>
        
            if(WorkOnit(input, i)
               ...
            ...
         );
    

非常感谢!

【问题讨论】:

【参考方案1】:

这取决于WorkOnIt 的详细信息。您是否对必须小心的外部可见对象使用任何同步方式。如果没有,那么你是安全的。

例如,如果您的 WorkOnIt 看起来像:

private void MyWorkOnIt(float[] input, int idx)

    lock(input)  /* ... */  // possible deadlock scenario

如果调用Execute 的代码锁定在同一个对象上,这可能会死锁:

lock(myInput)

    Execute(myInput, MyWorkOnIt);

一般来说,我会尝试让并行循环的代表完全独立于任何共享状态。如果我做不到 - 例如当我必须聚合项目时,我将使用其中一个使用本地状态的并行循环。

【讨论】:

非常感谢您的帮助!!我只是从数组中读取,所以你是对的,这不应该给我带来死锁。我对委托不是很熟悉,所以我担心在多线程中这可能会以某种方式干扰。但它现在似乎工作正常。【参考方案2】:

您可以使用相同的函数,但请注意,如果您需要使用在函数范围之外声明的数据,则需要确保这些数据类型的线程安全,例如使用锁定。

http://msdn.microsoft.com/de-de/library/system.threading.tasks.parallel(v=vs.110).aspx

编辑:当然,如果您认为 smtg 是这样的,那么您当然可以通过使用并行任务来生成死锁:

void myfunction(...) 
   lock (locker) 
       doSomethingWithAGlobalList(..);
       waitForOtherTasksDoingThingsWithThatList(..);
   

但这不是您的 Parallel.For 的问题,而是由进入 myfunction 的任何并发线程引起的

【讨论】:

非常感谢您的帮助!你是绝对正确的,这应该只会像你的例子那样造成僵局。我对委托不是很熟悉,所以我担心在多线程中这可能会以某种方式干扰。但它似乎工作正常。

以上是关于我可以在 Parallel.For 循环中使用相同的函数委托吗的主要内容,如果未能解决你的问题,请参考以下文章

在Parallel.For中,是否可以同步每个线程?

VB.NET 在 Parallel.for Synclock 内的嵌套循环中运行 sum 丢失信息

Parallel.for 循环执行

在另一个并行循环中调用函数时,函数中的“pragma omp parallel for”无效

测量Parallel.For的执行时间

Parallel.For(Foreach) 将创建多少个线程?默认 MaxDegreeOfParallelism?