自动并行化的策略

时间:2010-12-03 23:48:37

标签: c# multithreading algorithm parallel-processing

我正在构建一个基于节点的拖放编辑器,其中每个节点代表一个动作(例如,读取此文件,或对此数据进行排序等)。节点的输出和输入可以连接。

我想要实现的一个功能是automatic parallelization,因此如果路径分支出来,我可以自动开始一个线程来处理每个分支。然而,我担心一些问题:

  • 如果一个路径分支,但后来又加入了一起,我将需要以某种方式同步它们
  • 如果有多个起始节点(执行开始),则必须单独管理其路径,然后可能动态加入/合并
  • 我想限制创建多少个线程,这样我就不会突然有20个线程死锁

基本上,我想知道是否存在执行此类操作的任何策略(不是必须寻找代码;只是理论)。调度算法可以帮助吗?

感谢您的建议!我期待听到你的建议。

注意:我正在使用C#3.5,因此我无法使用任何有趣的并行任务功能。如果有必要,我会切换到C#4.0,但我想避免这种情况。

1 个答案:

答案 0 :(得分:3)

Task Parallel Library可能正是您正在寻找的。

我想你的基于节点的拖放编辑器看起来像这样:

Illustration

每个节点基本上都是任务。任务可以是任何东西 - 从磁盘读取文件,从Web下载一些数据或计算任何内容。

当任务完成后,它可以 ContinueWith 一个或多个其他任务,将旧任务的结果传递给新任务。

任务还可以包括等待多个任务完成。 WhenAll 这些任务完成后,此任务可以继续执行另一个任务,将所有任务的结果传递给新任务。

TPL将安排线程池上的所有这些任务,因此可以重用线程,并且每个任务不需要拥有自己的线程。 TPL将为其运行的系统找到最佳线程数。

Visual Studio Async CTP为C#的异步操作添加了本机语言支持,这使得使用Tasks非常简单有趣。

使用TPL,只需创建任务并根据节点布局进行组合即可。

上述示例的完整程序代码:

var t1 = Task.Factory.StartNew<int>(() => 42);

var t2a = t1.ContinueWith<int>(t => t.Result + 1);
var t2b = t1.ContinueWith<int>(t => t.Result + 1);

var t3a = t2a.ContinueWith<int>(t => t.Result * 2);
var t3b = t2b.ContinueWith<int>(t => t.Result * 3);

var t4 = TaskEx.WhenAll<int>(t3a, t3b)
               .ContinueWith<int>(t => t.Result[0] + t.Result[1]);

t4.ContinueWith(t => { Console.WriteLine(t.Result); });

Console.ReadKey();