【发布时间】:2018-09-10 23:13:15
【问题描述】:
我了解障碍可用于在第二阶段运行之前让多个任务同步完成。
我想让几个任务同步多个步骤,如下所示:
state is 1;
Task1 runs and pauses waiting for state to become 2;
Task2 runs and pauses waiting for state to become 2;
Task2 is final Task and causes the state to progress to state 2;
Task1 runs and pauses waiting for state to become 3;
Task2 runs and pauses waiting for state to become 3;
Task2 is final Task and causes the state to progress to state 3;
state 3 is final state and so all tasks exit.
我知道我可以在每个状态结束时启动新任务,但由于每个任务不会花费太长时间,我想避免为每个步骤创建新任务。
我可以使用 for 循环同步运行上述内容,但最终状态可能是 100,000,因此我希望使用多个线程来更快地运行该进程,因为该进程受 CPU 限制。
我尝试使用计数器来跟踪每个任务在完成时增加的已完成任务的数量。如果任务是要完成的最终任务,那么它将状态更改为下一个状态。所有已完成的任务然后使用while (iterationState == state) await Task.Yield 等待,但性能很糟糕,在我看来这是一种非常粗暴的做法。
完成上述工作的最有效方法是什么?必须有一个优化的工具来完成这项工作?
我正在使用Parallel.For,创建 300 个任务,每个任务需要运行多达 100,000 个状态。通过一个状态运行的每个任务在不到一秒的时间内完成,创建 300 * 100,000 个任务是一个巨大的开销,即使使用单个线程,同步运行整个任务也会更快。
所以我想创建 300 个任务并让这些任务在 100,000 个状态中同步移动。希望仅创建 300 个任务而不是 300 * 100,000 个任务的开销,以及任务之间优化同步的开销,将比在单个线程上同步执行时运行得更快。
每个状态必须完全完成才能运行下一个状态。
那么 - 这种情况下的最佳同步技术是什么?谢谢!
【问题讨论】:
-
我理解正确吗 - 您一次只能运行两个任务,并且为了移动到下一个状态,您必须等待两个都完成并且您可能有多达 100,000 个状态?
-
听起来你需要 Monitor.Pulse 和 Monitor.Wait
-
可以切换到dataflow库吗?
-
@IanMercer 这是问题所在 - 大多数执行时间不到一毫秒。有些需要数百毫秒。所以我的并行化代码对于绝大多数执行来说确实是在浪费时间,但是在较长的执行期间让 CPU 以 5% 的速度运行是一种资源浪费——我正在尝试找到一种有效管理那些 1ms 在设计时是未知的。
-
我认为@IanMercer 是正确的,他的解决方案比我的更干净。 Parallel.For 应该是最佳解决方案,并且具有基于它所运行的本地机器的“自动调整”本身的好处,而使用我的解决方案,您必须找出您移动到的每台机器的最佳线程数。话虽如此,但没有看到您尝试并行化的代码,这实际上只是提供解决方案的猜谜游戏。
标签: c#