C# 多线程入门
- 一. 基本概念
- 1. 进程
- 2. 线程
- 1. 基本理解
- 2. 多线程的好处
- 3. 使用多线程需要注意
- 1. 基本弃用
- 1. 对线程池的理解
- 2. 使用线程池好处
- 3. 使用线程池的注意事项
- 4. 线程池的简单使用
- 1. 简介
- 2. Task的简单使用
一. 基本概念
1. 进程
进程(Process)是系统进行资源分配和调度的基本单位,是操作系统结构的基础。(一般情况下,一个应用程序可以认为是一个进程。进程占用多少资源,并不是由进程本身决定。而是由这个进程分配的线程决定。也就是说操作系统是通过线程来管理程序资源的。
2. 线程
线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
二. 多线程
1. 基本理解
在进程中多个线程同时执行的时候,我们称为多线程。
【1】线程挂起: 就是我们说的暂停。挂起是用户主动发起的行为,可以主动恢复。(不释放CPU)
【2】线程睡眠: 挂起恢复需要主动完成,睡眠恢复则是自动完成的,因为睡眠有一个睡眠时间,睡眠时间到则恢复到就绪态
【3】线程阻塞: 阻塞是一种被动的行为,在抢占资源中得不到资源,被动的挂起在内存,等待某种资源或信号量(即有了资源)将他唤醒。(释放CPU,不释放内存)
2. 多线程的好处
1.在多CPU和多核情况下,真正实现并行运行。
2.提升CPU的利用率(比如遇到某些耗时操作时(等待输入、监听数据等),使用多线程允许其他线程继续执行,从而避免整个进程被阻塞,从而提高了CPU的利用率,使程序的响应速度更快。)
总而言之:使用多线程可以充分的利用 CPU 和 I/O 的利用率,CPU 密集型程序和I/O 密集型程序都可以考虑使用多线程。
注意:
1、在单核时代,从微观角度来讲,同一时刻只能有一个线程在处理。但是因为CPU速度太快,察觉不到,看起来是同一时刻执行了不同的操作,所以宏观角度来说是多线程并行运行的。(单核CPU处理CPU密集型程序,并不太适合使用多线程)
2、多核多CPU时代,能够真正实现线程并行运行。
3. 使用多线程需要注意
(1)线程也是程序,所以线程需要占用内存,线程越多,占用内存也越多。
(2)多线程需要协调和管理,所以需要占用CPU时间以便跟踪线程。
(3)线程之间对共享资源的访问会相互影响,必须解决争用共享资源的问题。
(4)线程太多会导致控制太复杂,最终可能造成很多程序缺陷。
三. Thread
1. 基本弃用
基本很少直接使用了,在这里不多讲,讲了也没多大意思。
四. ThreadPool
1. 对线程池的理解
相当于有一个专门装线程的池;如果需要使用线程;就到池子里面去获取线程来使用;使用完毕,就再放回池子里。
2. 使用线程池好处
使用多线程时,如果系统不断的启动和关闭新线程,成本非常高,会过渡消耗系统资源,以及过渡切换线程的危险,从而可能导致系统资源的崩溃。这时,可以使用线程池降低系统资源的消耗,实现线程重复利用,提高线程的可管理性,同时减少线程创建的时间可以提高响应速度。
3. 使用线程池的注意事项
a. 设置线程数量要谨慎。(因为它是全局的,设置不当会造成影响,因为task、Parallel、async/await 中的线程也来自线程池)
b. 线程池中的线程均为后台线程,并且不能修改为前台线程。
c. 不能给入池的线程设置优先级或名称。
d. 入池的线程只适合时间较短的任务。
4. 线程池的简单使用
五. Parallel
并行,让多个线程池线程并行工作。
六. Task
1. 简介
.NET4.0以后,微软建议使用Task
Task可以说是Thread和ThreadPool的结合,Task是对计算机资源线程操作的一个封装,封装包含了很多丰富的API(例如:等待、终止、返回值…优化线程操作的功能),在性能上,资源开销上,都得到很好的优化,性能优于ThreadPool。