我可以在 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 循环中使用相同的函数委托吗的主要内容,如果未能解决你的问题,请参考以下文章
VB.NET 在 Parallel.for Synclock 内的嵌套循环中运行 sum 丢失信息