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

目录

并发和并行

一.并发

定义

特点

代码示例

代码解释

二.并行

定义

特点

在C#中的体现

代码示例

代码解释

三.并发和并行的区别

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

1.考虑任务类型

2.代码示例

3.注意事项

五.总结


并发和并行

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

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

一.并发

定义

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

特点

  1. **任务交替进行:**在单核处理器上,操作系统通过时间片轮转的方式,使多个任务看起来像是同时进行的

  2. **资源共享:**并发任务共享同一资源,需要协调和同步,避免冲突

  3. **重点在于结构化程序:**并发性使程序更易于建模和维护,因为它将复杂的流程分解为独立的任务

  4. 在C#中的体现:

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

代码示例

cs 复制代码
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);
        }
    }   
}

代码解释

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

二.并行

定义

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

特点

  1. **物理上的同时性:**需要硬件支持,如多核 CPU 或多处理器系统
  2. 提高性能:通过同时执行多个计算密集型任务来缩短总的执行时间
  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. 基于任务的并行模型,充分利用多核处理器的性能

代码示例

cs 复制代码
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("计算完成。");
    }
}

代码解释

Parallel.For方法会自动将循环迭代分配到多个线程,在多个CPU核心上同时运行

  1. 适用于CPU密集型计算任务,可以显著提高性能

三.并发和并行的区别

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

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

1.考虑任务类型

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

2.代码示例

并发异步调用:

cs 复制代码
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);
        }
    }   
}

并行处理数据:

cs 复制代码
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# 中,通过异步编程,线程,任务和并行类库,可以灵活地实现并发和并行,满足不同应用场景的需求
相关推荐
猷咪6 分钟前
C++基础
开发语言·c++
IT·小灰灰7 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧9 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q9 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳010 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾10 分钟前
php 对接deepseek
android·开发语言·php
2601_9498683613 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计27 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673739 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
一匹电信狗41 分钟前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl