小赖子的英国生活和资讯

.NET 4.0 (4.5) 之后强大的平行 For, ForEach 语句用于多线程执行

阅读 桌面完整版

.NET 4.0 之后 (e.g. 4.5) 添加了并行 For, ForEach 的支持.如果你的代码里有很多处 SIMD (单指令,多数据 Single Instruction Multiple Data). 就可以通过 Parallel.ForParallel.ForEach 来进行多线程.使用方法非常简单:你不需要再手动创建几个线程,然后同时启动多线程,并等待它们的执行(同步).

首先,你需要引用这两个单元.

1
2
using System.Threading;
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;

为了演示方便,建立了一个长度为10的数组,元素是 Double 类型.

1
double[] nums = new double[10];
double[] nums = new double[10];

传统给它们一一赋值,比如这样:

1
2
3
for (int i = 0; i < nums.length; i ++) {
    nums[i] = i;
} // helloacm.com
for (int i = 0; i < nums.length; i ++) {
    nums[i] = i;
} // helloacm.com

现在,我们只需要 使用 Parallel.For; 第一个参数是索引下标,第二个参数是索引上标,然后第三个参数指定了操作.前两个参数指定了下标范围.

1
2
3
4
5
6
Parallel.For(0, nums.Length - 1, 
    i =>
    {
        nums[i] = i;
    }
); // helloacm.com
Parallel.For(0, nums.Length - 1, 
    i =>
    {
        nums[i] = i;
    }
); // helloacm.com

类似的,我们可以用 Parallel.ForEach,以下代码把数组的值显示出来.第一个参数是数据目标.第二个参数指定了并行的指令.

1
2
3
4
5
6
Parallel.ForEach(
    nums, num =>
    {
        Console.WriteLine("Number {0:R} on thread {1}", num, Thread.CurrentThread.ManagedThreadId);
    }
);
Parallel.ForEach(
    nums, num =>
    {
        Console.WriteLine("Number {0:R} on thread {1}", num, Thread.CurrentThread.ManagedThreadId);
    }
);

由此可见,多线程处理数据变得非常容易简单.对于 ForEach, 来说,修改目标数据变量 例如上面例子中的变量 num 并不能改变原数据(数组)的值.这个变量是一个独立的值拷贝,只能读取.

不要假定并行的For一定会比较快.在数据量小的情况还有一些集合对象中, 在缓存,CPU预判断的帮助下, 顺序执行反而会更快.

结合以上两个程序片断,可以得到类似这样的输出.

Number 0 on thread 9
Number 0 on thread 9
Number 7 on thread 15
Number 5 on thread 14
Number 4 on thread 12
Number 8 on thread 16
Number 1 on thread 10
Number 2 on thread 11
Number 3 on thread 6
Number 6 on thread 13

英文同步: https://helloacm.com/how-to-speed-up-parallel-processing-using-parallel-for-foreach-in-c-net-4-0-or-above/

强烈推荐

微信公众号: 小赖子的英国生活和资讯 JustYYUK

阅读 桌面完整版
Exit mobile version