我在嵌套的Parallel.For循环(vb.net)中调用子例程MyPartsMatrix。MyPartsMatrix需要一个名为“ByRef”的变量,该变量将传递给MyPartsMatrix,因为此值是在MyPartsMatrix子例程中修改的。我需要在执行子例程MyPartsMatrix之后获取并存储这个值。
当我运行这段代码的并行版本时,与使用常规嵌套For...Next循环的非并行版本相比,“未填充”变量会产生一个不同的值。我不明白为什么会这样。
从Parallel.For循环内部调用另一个子例程是线程安全的吗?
这个变量“未填充”的线程安全吗?
Dim ConcurrentListofResults As ConcurrentQueue(Of FindBestResults)
ConcurrentListofResults = New ConcurrentQueue(Of FindBestResults)
Dim x = 5, y = 5
Parallel.For(0, x, Sub(oD)
Parallel.For(0, y, Sub(oT)
Dim unfilled As Integer = 0
MyPartsMatrix (oD, oT, unfilled)
'Create a FBS item to add to the concurrent list collection
Dim FBSResultsItem = New FindBestResults
FBSResultsItem.oD = oD
FBSResultsItem.oT = oT
FBSResultsItem.unfilled = unfilled
'Add this item to the Concurent collection
ConcurrentListofResults.Enqueue(FBSResultsItem)
End Sub)
End Sub)
'Get best result.
Dim bestResult As FindBestResults
For Each item As FindBestResults In ConcurrentListofResults
If item.unfilled < bestResult.unfilled Then
bestResult.oD = item.oD
bestResult.oT = item.oT
bestResult.unfilled = item.unfilled
End If
Next
Public Sub MyPartsMatrix (ByVal oD As Integer, ByVal oT As Integer, ByRef unfilled As Integer)
'....do stuff with the unfilled variable....
'unfilled is a counter that is incremented while we run through the PartsMatrix
unfilled = unfilled + 1
End Sub如果这不是线程安全的,有没有其他方法来写这个,使“未填充”的变量是线程安全的,或者使调用另一个子例程线程安全?
发布于 2016-09-15 17:02:44
如果没有MakeSchedule (您在另一个地方调用了MyMakePartsMatrix )的定义,就不可能说它是否是线程安全的。
要成为threadsafe,sub不需要修改任何内容,只需修改unfilled。这将确保使用相同的输入多次调用它将始终产生相同的输出。我也建议转换成一个函数,因为我发现这更容易理解发生了什么。
另一点是:
如果你不嵌套并行循环,你的性能会更好。在启动第二个循环之前,您当前正在等待内循环完成。如果你使用更大的x+y值,那么类似于代码的东西会工作得更好。
Dim scenarios = From x2 In Enumerable.Range(0, x)
From y2 In Enumerable.Range(0, y)
Select New With {x2, y2}
Parallel.ForEach(scenarios, Sub(s)
End Sub)https://stackoverflow.com/questions/39503795
复制相似问题