当前位置: 首页 > article >正文

C# 并发和并行的区别--16

目录

并发和并行

一.并发

定义

特点

代码示例

代码解释

二.并行

定义

特点

在C#中的体现

代码示例

代码解释

三.并发和并行的区别

四 .如何在C#中选择并发还是并行

1.考虑任务类型

2.代码示例

3.注意事项

五.总结


并发和并行

在编程领域,并发并行是两个密切相关但是又有区别的概念

它们都涉及到同时处理多个任务,但在执行方式,目的和实现上存在差异

一.并发

  1. 定义

    并发是指一个系统能够同时处理多个任务的能力.在并发执行中,多个任务在逻辑上是“同时”进行的,但在物理上可能并不是同时进行,而是通过在任务之间快速切换实现的
  2. 特点

    1. 任务交替进行:在单核处理器上,操作系统通过时间片轮转的方式,使多个任务看起来像是同时进行的
    2. 资源共享:并发任务共享同一资源,需要协调和同步,避免冲突
    3. 重点在于结构化程序:并发性使程序更易于建模和维护,因为它将复杂的流程分解为独立的任务
  3. 在C#中的体现:

    • 异步编程:
      • 使用async和await关键字,方法可以在等待I/O操作时释放线程
      • 适用于密集型任务,如文件读写,网络通信
    • 线程(Thread)和任务(Task):
      • 使用System.Threading命名空间下的Thread类
      • 使用System.Threading.Tasks命名空间下的Task类,实现更高级的并发模型
  4. 代码示例

    using System;   
    using System.Net.Http;   
    using System.Threading.Tasks;
       
    class Program   
    {
        static async Task Main()
        {
            Task<string> task1 = GetDataAsync("http://example.com/data1");
            Task<string> task2 = GetDataAsync("http://example.com/data2");
    
            // 并发执行两个异步任务
            string[] results = await Task.WhenAll(task1, task2);
    
            Console.WriteLine(results[0]);
            Console.WriteLine(results[1]);
        }
    
        static async Task<string> GetDataAsync(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                return await client.GetStringAsync(url);
            }
        }   
    }
    
  5. 代码解释

    • 在上述代码中,GetDataAsync方法是异步的,调用它并不会阻碍主线程
    • Task.WhenAll方法并发地等待多个任务完成,尽管在单核CPU上这些任务并不是物理上同时执行的

二.并行

  1. 定义

    1. 并行是指在物理上同时执行多个任务.在并行执行中,多个任务真正地在同一时间被多个处理器或多个处理器核心执行
  2. 特点

    1. 物理上的同时性:需要硬件支持,如多核 CPU 或多处理器系统
    2. 提高性能:通过同时执行多个计算密集型任务来缩短总的执行时间
    3. 任务独立性:并行任务通常是相互独立的,减少了同步和竞争的需要
  3. 在C#中的体现

    1. 并行LINQ(PLINQ):
      1. 使用并行化技术加速LINQ查询
      2. 位于System.LINQ命名空间
    2. 并行类:
      1. 位于System.Threading.Tasks下命名空间
      2. 提供Parallel.For和Parallel.ForEach等方法,轻松实现数据并行
    3. 任务并行库(Task Parallel Library,TPL):
      1. 基于任务的并行模型,充分利用多核处理器的性能
  4. 代码示例

    using System;   
    using System.Threading.Tasks;
       
    class Program   
    {
        static void Main()
        {
            // 定义一个大型数组
            int[] numbers = new int[100000000];
            Parallel.For(0, numbers.Length, i =>
            {
                numbers[i] = i * i;
            });
    
            Console.WriteLine("计算完成。");
        }
    }
    

  5. 代码解释

    Parallel.For方法会自动将循环迭代分配到多个线程,在多个CPU核心上同时运行
    1. 适用于CPU密集型计算任务,可以显著提高性能

三.并发和并行的区别

并发并行
定义系统处理多个任务的能力,通过任务切换,实现逻辑上的同时执行多个任务在物理上同时执行,需要多核或多处理器硬件支持
执行任务交替进行,可能不是同时执行任务真正地同时执行
目的提高资源利用率和系统吞吐量,提高程序的响应性缩短任务的执行时间,提高计算性能
适用I/O 密集型任务,事件驱动程序,GUI 应用计算密集型任务,如科学计算,大数据处理
实现线程,异步编程,任务调度多线程加上多处理器或多核处理器,并行算法
挑战需要处理任务同步,共享资源竞争,避免死锁和竞态条件分解任务,负载均衡,减少线程间通信和同步开销

四 .如何在C#中选择并发还是并行

1.考虑任务类型

  • I/O密集型任务(网络请求,文件读写):
    • 使用并发类型,异步编程
    • 因为I/O操作速度慢,线程在等待I/O时可以切换执行其他任务,提高效率
  • CPU密集型任务(复杂计算,数据处理):
    • 使用并行模型,充分利用CPU
    • 通过并行算法将任务分解为可同时执行的子任务

2.代码示例

并发异步调用:

using System;   
using System.Net.Http;   
using System.Threading.Tasks;
   
class Program   
{
    static async Task Main()
    {
        Task<string> task1 = GetDataAsync("http://example.com/data1");
        Task<string> task2 = GetDataAsync("http://example.com/data2");

        // 并发执行两个异步任务
        string[] results = await Task.WhenAll(task1, task2);

        Console.WriteLine(results[0]);
        Console.WriteLine(results[1]);
    }

    static async Task<string> GetDataAsync(string url)
    {
        using (HttpClient client = new HttpClient())
        {
            return await client.GetStringAsync(url);
        }
    }   
}

并行处理数据:

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

class Program
{
   static void Main()
   {
       int[] numbers = Enumerable.Range(0, 1000000).ToArray();

       var evenNumbers = numbers.AsParallel()
                                .Where(n => n % 2 == 0)
                                .ToArray();

       Console.WriteLine($"找到 {evenNumbers.Length} 个偶数。");
   }
}

3.注意事项

  • 线程安全和同步
    • 无论是并发还是并行,都需要处理共享数据的同步问题
    • 使用锁,互斥量,信号量和无锁编程技术,避免数据竞争
  • 性能权衡
    • 并行化需要考虑线程创建和上下文切换的开销
    • 任务过小,可能得不偿失;任务过大,可能无法充分利用并行性
  • 异常处理
    • 并行任务中的异常处理需要格外注意,使用AggregateException捕获并处理

五.总结

  • 并发关注在单个处理器上交替执行多个任务,提高资源利用率和响应性
  • 并行关注在多个处理器上同时执行多个任务,缩短执行时间,提升计算性能
  • 在 C# 中,通过异步编程,线程,任务和并行类库,可以灵活地实现并发和并行,满足不同应用场景的需求

http://www.kler.cn/a/506928.html

相关文章:

  • springcloud中的Feign调用
  • 闪豆多平台视频批量下载器
  • macos arm 本地/docker/本地k8s 安装jupyterhub 并登陆
  • SpringBoot链接Kafka
  • ASP.NET Core - 缓存之分布式缓存
  • RabbitMQ(四)
  • JavaScript分页的制作
  • 【WRF-Urban】新增静态输入数据:URB_PARAM、FRC_URB2D、AHE等
  • redis性能优化参考——筑梦之路
  • 复古怀旧美感35mm胶片模拟色调颗粒汽车商业摄影Lightroom调色预设 Mike Crawat 2024 35MM FILM LOOK PRESETS
  • polarDB报错column reference is ambiguous
  • 手机壁纸设计技巧:打造个性化视觉盛宴
  • zustand 切片模式使用,persist 中间件持久化状态
  • 使用 Kubernetes 实现负载均衡
  • 初步认识 Neo4j 图数据库
  • 《零基础Go语言算法实战》【题目 4-3】请用 Go 语言编写一个验证栈序列是否为空的算法
  • Linux(CentOS/CTyunOS)缺少GBK、GB2312中文字符集
  • 【设计模式-结构型】代理模式
  • RK3568笔记七十四:AP配网实现
  • VLAN是什么?有什么作用?
  • 高效构建与部署Python Web应用:FastAPI的测试与持续集成
  • 基于单片机的智能输液系统
  • C#中委托和函数类的关系
  • 11-2.Android 项目结构 - themes.xml 文件基础解读
  • 微信小程序web-view 外链白屏, 分享后白屏?
  • 解决关于Xcode16提交审核报错