C#并发编程之【三】并行编程简介

一、何时使用并行编程

有大量的计算任务,并且这些任务能分割成几个互相独立的任务块。并行编程可临时提高CPU 利用率,以提高吞吐量,若客户端系统中的CPU经常处于空闲状态,这个方法就非常有用,但通常并不适合服务器系统。大多数服务器本身具有并行处理能力,例如ASP .NET可并行地处理多个请求。某些情况下,在服务器系统中编写并行代码仍然有用(如果你知道并发用户数量会一直是少数)。但通常情况下,在服务器系统上进行并行编程,将降低本身的并行处理能力,并且不会有实际的 好处。

二、并行编程的两种形式
  • 数据并行(data parallelism):指有大量的数据需要处理,并且每一块数据的处理过程基本上是彼此独立的
  • 任务并行(task parallelim):指需要执行大量任务,并且每个任务的执行过程基本上是彼此独立的

任务并行可以 是动态的,如果一个任务的执行结果会产生额外的任务,这些新增的任务也可以加入任务池。

三、实现数据并行
  1. 使用 Parallel.ForEach 方法,它类似于 foreach 循环,应尽可能使用这种做法。
    Parallel 类也提供 Parallel.For 方法,这类似于 for 循环,当数据处理过程基于一个索引 时,可使用这个方法。
    下面是使用 Parallel.ForEach 的代码例子:
 void RotateMatrices(IEnumerable<Matrix> matrices, float degrees)   
  {         
  	Parallel.ForEach(matrices, matrix => matrix.Rotate(degrees));     
  }
  1. 使用 PLINQ(Parallel LINQ), 它为 LINQ 查询提供了 AsParallel 扩展。
    跟 PLINQ 相比,Parallel 对资源更加友好,Parallel 与系统中的其他进程配合得比较好 , 而 PLINQ 会试图让所有的 CPU 来执行本进程。Parallel 的缺点是它太明显。很多情况下, PLINQ 的代码更加优美。
  IEnumerable<bool> PrimalityTest(IEnumerable<int> values)     
  {         
  	return values.AsParallel().Select(val => IsPrime(val));     
  }

不管选用哪种方法,在并行处理时有一个非常重要的准则:每个任务块要尽可能的互相独立。

四、实现任务并行

Parallel 类的 Parallel.Invoke 方法可以执行“分叉 / 联合”(fork/join)方式的任务并行。
调用该方法时,把要并行执行的委托(delegate)作为传入 参数:

void ProcessArray(double[] array)     
{         
	Parallel.Invoke(
		() => ProcessPartialArray(array, 0, array.Length / 2),             
		() => ProcessPartialArray(array, array.Length / 2, array.Length)
			);    
 } 
void ProcessPartialArray(double[] array, int begin, int end)     
{         
// CPU 密集型的操作……     
}

现在 Task 这个类也被用于异步编程,但当初它是为了任务并行而引入的。任务并行中使 用的一个 Task 实例表示一些任务。可以使用 Wait 方法等待任务完成,还可以使用 Result 和 Exception 属性来检查任务执行的结果。直接使用 Task 类型的代码比使用 Parallel 类 要复杂,但是,如果在运行前不知道并行任务的结构,就需要使用 Task 类型。如果使 用动态并行机制,在开始处理时,任务块的个数是不确定的,只有继续执行后才能确 定。通常情况下,一个动态任务块要启动它所需的所有子任务,然后等待这些子任务执 行完毕。为实现这个功能,可以使用 Task 类型中的一个特殊标志:TaskCreationOptions. AttachedToParent。

C# 是一种广泛应用于Windows平台的面向对象编程语言,其并发编程并行编程是设计高性能和可扩展应用程序的关键特性。以下是C#中并发和并行编程的一些核心概念: 1. **并发(Concurrent Programming)**:在单个处理器上同时执行多个任务或线程,这些任务可以在不同的时间点或以不同的频率交替执行。C# 提供了Thread类和Task类来进行并发操作,通过异步编程模型(async/await)可以更优雅地管理线程。 2. **线程(Threads)**:在C#中,线程是执行代码的基本单位。使用System.Threading命名空间中的Thread类可以创建和管理线程,包括启动、同步、中断等。 3. **Task Parallel Library (TPL)**:这是C#的一个库,提供了更高级别的并行编程支持,比如Task类,它可以更容易地进行并行任务分派,提供异步阻塞和非阻塞模式,以及自动的线程池管理。 4. **线程池(Thread Pool)**:线程池是预先创建的一组线程,用于处理短时间的、可复用的、并发任务。C#的线程池由ThreadPool类管理,可以提高资源利用率并避免频繁创建和销毁线程的开销。 5. **并发安全(Concurrency Safety)**:C#提供了锁(lock)、Monitor、Interlocked等同步机制来确保并发环境下的数据一致性。此外,还推荐使用async/await和Concurrent Collections(如ConcurrentDictionary)等特性避免竞态条件。 6. **并行计算(Parallel Computation)**:C#并行计算涉及大规模数据集的分解和并行处理,可以利用多核处理器的性能。Parallel LINQ(PLINQ)是一个简化并行查询和迭代的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洋洋脚踝的金铃响了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值