中国大学慕课-C#程序设计-第11讲-多线程与异步编程 之 并行编程

中国大学慕课-C#程序设计-第11讲-多线程与异步编程 之 并行编程

1. 并行编程

并行编程(C#4, 5以上),简单来时,就是多个CPU可以同时执行多个任务;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. Task.Run需要一个委托,常用的是lamda表达式,Task.Run执行某个任务并返回结果;
  2. Task.Run后面的语句会继续并行执行;
  3. double result = task.Result; 等待直到获得结果;
  4. Task.WaitAll(task数组),等待Task.Run的任务都执行完了,再接着往下走;
  5. task.ContinueWith(另一个task),让 task任务一个接一个的执行;

Demo

using System;
using System.Threading;
using System.Threading.Tasks;

class Demo
{
    private static int i;
    static void Main(string []args)
    {
        Task<double>[] tasks = { Task.Run( () => SomeFun()), Task.Run( () => SomeFun()) };
  
        for ( i = 0; i < tasks.Length; i++ )
        {         
            Console.WriteLine(tasks[i].Status);
            Console.WriteLine(tasks[i].Result);
        }

        Task.WaitAll(tasks);
    }

    public static double SomeFun()
    {
        Thread.Sleep(5000);
        return 0;
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Demo Parallel.Invoke

using System;
using System.Threading;
using System.Threading.Tasks;
class TestParallelInvoke
{
    static void Main(string[] args)
    {
        Action[] actions = { new Action(DoSometing), DoSometing };
        Parallel.Invoke( actions );  
        // actions执行完后才会去执行下面
        Console.WriteLine("主函数所在线程"+Thread.CurrentThread.ManagedThreadId);
        Console.ReadKey();
    }

    static void DoSometing()
    { 
        Console.WriteLine("函数所在线程"+Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(2000);
    }
}

Demo Parallel.For

using System;
using System.Threading;
using System.Threading.Tasks;

class T
{
    static void Main(string[] args)
    {
        Parallel.For(0, 10, i =>
        {
            Console.WriteLine("i={0}, fac={1}, 线程id={2}",
                i, Calc(i),
                Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(10);
        });
        Console.ReadLine();
    }

    static double Calc(int n)
    {
        double f = 1;
        for(int i=1; i<=n; i++ ) f*=i;
        Thread.Sleep(1000);
        return f;
    }

}

在这里插入图片描述
Demo Parallel.ForEach

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;

class T
{
    static void Main(string []args)
    {
        List<double> dList = new List<double>();
        for (int i = 0; i <= 4 ; i++)
        {
            dList.Add(i * i);
        }
        ParallelLoopResult loop_result = Parallel.ForEach(dList, (double x, ParallelLoopState loop_state) =>
        {
            if (x == 400) 
            {
                loop_state.Break();           
            }
             Console.WriteLine("x = {0}, thread id = {1} \n", x, Thread.CurrentThread.ManagedThreadId);
        });

        Console.WriteLine("IsCompleted: {0}", 
        loop_result.IsCompleted);

        Console.WriteLine("BreakValue: {0}", 
        loop_result.LowestBreakIteration.HasValue);

        Console.ReadLine(); 
    }
}

在这里插入图片描述
Demo 并行计算矩阵

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoParallelComputeMatric
{
    class Program
    {
        static void Main(string[] args)
        {
            int m = 480;
            int n = 640;
            int t = 640;
            double[,] mat_A = new double[m, n];
            double[,] mat_B = new double[n, t];
            double[,] mat_R_1 = new double[m, t];
            double[,] mat_R_2 = new double[m, t];

            InitMatrix(mat_A);
            InitMatrix(mat_B);
            InitMatrix(mat_R_1);
            InitMatrix(mat_R_2);

            Console.WriteLine("矩阵乘法");
            Stopwatch sw = new Stopwatch();
            sw.Start();
            MultiMatrixNormal(mat_A, mat_B, mat_R_1);
            sw.Stop();
            Console.WriteLine("普通方法所用时间:" + sw.ElapsedMilliseconds);

            sw.Restart();
            MultiMatrixParallel(mat_A, mat_B, mat_R_2);
            sw.Stop();
            Console.WriteLine("并行方法所用时间:" + sw.ElapsedMilliseconds);

            Console.ReadLine();

        }

        static void InitMatrix(double[,] mat)
        {
            int m = mat.GetLength(0);
            int n = mat.GetLength(1);
            Random rnd = new Random();

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    mat[i, j] = rnd.Next();
                }
            }
        }

        static void MultiMatrixNormal(double[,] mat_A, double[,] mat_B, double[,] mat_R)
        {
            int m = mat_A.GetLength(0);
            int n = mat_A.GetLength(1);
            int t = mat_R.GetLength(1);

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < t; j++)
                {
                    double temp = 0;
                    for (int k = 0; k < n; k++)
                    {
                        temp = mat_A[i, k] * mat_B[k, j];
                    }
                    mat_R[i, j] = temp;
                }
            }
        }

        static void MultiMatrixParallel(double[,] mat_A, double[,] mat_B, double[,] mat_R)
        {
            int m = mat_A.GetLength(0);
            int n = mat_A.GetLength(1);
            int t = mat_R.GetLength(1);

            Parallel.For(0, m, i =>
            {
                for (int j = 0; j < t; j++)
                {
                    double temp = 0;
                    for (int k = 0; k < n; k++)
                    {
                        temp = mat_A[i, k] * mat_B[k, j];
                    }
                    mat_R[i, j] = temp;
                }
            });
        }
    }
}

运行结果:
在这里插入图片描述

在这里插入图片描述
Demo

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace Demo_Linq
{
    class Program
    {
        const int count = 10000000;

        static void Main(string[] args)
        {
            var dic = LoadData();
            Stopwatch watch = new Stopwatch();

            //串行读取
            watch.Start();
            var query_1 = (from n in dic.Values where n.Age > 20 && n.Age < 25 select n).ToList();
            watch.Stop();
            Console.WriteLine("串行计算耗费时间{0}", watch.ElapsedMilliseconds);

            //并行读取
            watch.Restart();
            var query_2 = (from n in dic.Values.AsParallel() where n.Age > 20 && n.Age < 25 select n).ToList();
            watch.Stop();
            Console.WriteLine("并行计算耗费时间{0}", watch.ElapsedMilliseconds);

            Console.ReadLine();

        }

        //ConcurrentDictionary 表示可由多个线程同事访问的键/值对的线程安全集合
        public static ConcurrentDictionary<int, Student> LoadData()
        {
            ConcurrentDictionary<int, Student> stu_dic = new ConcurrentDictionary<int, Student>();

            Parallel.For(0, count, (i) =>
            {
                Student single_stu = new Student()
                {
                    ID = i,
                    Name = "n" + i,
                    Age = i % 151,
                    CreateTime = DateTime.Now.AddMilliseconds(i)
                };
                stu_dic.TryAdd(i, single_stu);
            });
            
            return stu_dic;
        }
    }


    public class Student
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public DateTime CreateTime { get; set; }
    }
}

在这里插入图片描述
count小的时候还是建议使用串行模式,效率比并行要快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值