zoukankan      html  css  js  c++  java
  • 《C#并发编程经典实例》学习笔记—3.1 数据的并行处理

    问题

    有一批数据,需要对每个元素进行相同的操作。该操作是计算密集型的,需要耗费一定的时间。

    解决方案

    常见的操作可以粗略分为 计算密集型操作 和 IO密集型操作。计算密集型操作主要是依赖于CPU计算,所以可以最大限度利用多核CPU的并行操作非常适合计算密集型操作。图像操作是比较常见的计算密集型操作,图像操作一般是借助矩阵存储图像数据,该书作者就举了矩阵旋转为例。
    思路是借助Parallel.ForEach实现并行操作。
    伪代码如下

    void RotateMatrices(IEnumerable<Matrix> matrices, float degrees)
    {
        Parallel.ForEach(matrices, matrix => matrix.Rotate(degrees));
    }
    

    当前循环处理无效值时,可能需要停止该循环,实现如下

    void InvertMatrices(IEnumerable<Matrix> matrices)
    {
        Parallel.ForEach(matrices, (matrix, state) =>
        {
            if (!matrix.IsInvertible)
                state.Stop();
            else
                matrix.Invert();
        });
    }
    

    而如果是想要取消整个并行循环,则需要借助CancellationToken,即可以有一个取消按钮,点击取消按钮,应取消循环操作。

    void RotateMatrices(IEnumerable<Matrix> matrices, float degrees,
    CancellationToken token)
    {
        Parallel.ForEach(matrices,
        new ParallelOptions { CancellationToken = token },
        matrix => matrix.Rotate(degrees));
    }
    

    另:当一个全局变量在并行循环内部被操作时,则需要考虑多进程共享状态。因为并行循环的每个循环很可能在不同的线程中运行。

    // 注意,这不是最高效的实现方式。
    // 只是举个例子,说明用锁来保护共享状态。
    int InvertMatrices(IEnumerable<Matrix> matrices)
    {
        object mutex = new object();
        int nonInvertibleCount = 0;
        Parallel.ForEach(matrices, matrix =>
        {
            if (matrix.IsInvertible)
            {
                matrix.Invert();
            }
            else
            {
                lock (mutex)
                {
                    ++nonInvertibleCount;
                }
            }
        });
        return nonInvertibleCount;
    }
    

    《C#并发编程经典实例》学习笔记-第一章并发编程概述 - repeatedly - 博客园 ,我提到了并行操作的两种方式,一种是Parallel,另一种是PLINQ(Parallel LINQ)。所以上述操作也可以使用PLINQ实现。

    两者是有区别的,区别如下:

    Parallel 类和 PLINQ 之间有一个区别:PLINQ 假设可以使用计算机内所有的CPU 核,而 Parallel 类则会根据 CPU 状态的变化动态地调整。

    相信对C#语法比较熟悉的应该能看出来,Parallel.ForEach是并行foreach循环,那么并行for循环对应的方法是什么呢?是Parallel.For 方法。

  • 相关阅读:
    ACM进阶
    hdu 2018 母牛的故事
    hdu 2084 数塔
    动态规划算法
    hdu 1003 Max sum
    hihocoder 1037 数字三角形
    UDP和TCP的区别(转)
    JS简单的图片左右滚动
    C# MD5加密的方法+一般处理程序使用Session+后台Json序列化
    CSS DIV 独占一行,清除左右两边的浮动
  • 原文地址:https://www.cnblogs.com/AlienXu/p/Parallel-ForEach.html
Copyright © 2011-2022 走看看