在多线程编程中,并发与并行是两个容易混淆的概念。请解释并发和并行的本质区别,并说明在 C# 语言中分别可以采用哪些技术或手段来实现并发与并行?
考察说明
考查对并发与并行概念的理解,以及在 C# 中实现并发与并行的具体技术知识。
回答思路
- 【回答框架 1】并发指多个任务在同一时间段内交替执行,宏观上同时进行,微观上可能串行;并行指多个任务在同一时刻真正同时执行,需要多核或分布式支持。区别在于时间片是否重合,并行的核心是同时,并发的核心是交替。
- 【回答框架 2】在 C# 中实现并发的方式包括:多线程(Thread 或 ThreadPool)、异步编程(async/await、Task)、以及协程(如 Unity 中的协程,但严格说并非语言级)。这些技术主要解决 CPU 等待或 I/O 阻塞时的资源利用问题,通过任务切换、同步机制(如 lock、Monitor、Semaphore)来保证线程安全。
- 【回答框架 3】实现并行主要依靠并行编程库,如 Parallel 类(Parallel.For、Parallel.Invoke)、Parallel LINQ(PLINQ)以及 Task 并行库(TPL),它们会利用多核 CPU 将数据或任务拆分到多个线程上真正同时执行。此外,C# 8.0 引入的 IAsyncEnumerable 可以用于异步流处理,与并行无关。
- 【回答框架 4】选择并发还是并行取决于场景:若任务是 I/O 密集型的(如网络请求、文件读写),使用异步并发更高效;若任务是 CPU 密集型的(如大量计算),则通过并行拆分到多核提升吞吐量。需注意并行需要硬件支持,且会引入线程同步开销。
- 【回答框架 5】在 C# 中实现并发时,常配合线程安全集合(如 ConcurrentBag、ConcurrentDictionary)和原子操作(Interlocked),避免数据竞争;实现并行时需考虑数据分区和任务粒度,过细的粒度会导致同步开销超过收益。
- 【关键点 1】并发的核心是任务交替执行,并行的核心是任务同时执行。
- 【关键点 2】在 C# 中,并发通常使用 Thread、Task、async/await 实现;并行使用 Parallel、PLINQ 或 TPL。
- 【关键点 3】并行受限于 CPU 核数,并发受限于资源利用效率。
- 【关键点 4】I/O 密集型任务适合异步并发,CPU 密集型任务适合并行分解。
- 【关键点 5】线程安全需通过同步机制或并发集合保证,否则会出现数据竞争。