多任务
- 同一个时间有多个任务在执行
- python程序默认是单任务
线程
- 线程概念
- 线程,可简单理解为是程序执行的一条分支,也是程序执行流的最小单元。
- 线程是被系统独立调度和分底的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程为其它线程共享进程所拥有的全部资源。

主线程
当一个程序后动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程,简而言之;程序后动就会创建一个主线程。
Copy主线程的重要性有两方面:
1)是产生其他子线程的线程;
2)通常它必须最后完成执行比如执行各种关闭动作·
子线程
- 可以看做是程序执行的一条分支,当子线程后动后会和主线程一起同时执行
- 主线程会等待所以子线程结束之后再结束
| |
线程数量
- 目标
- 能够如何查看正在活动的线程数量
- 1.查看线程数量
threading.enumerate()获取当前所有活跃的线程对象列表。使用len()对列表求长度可以看到当前活跃的线程的个数
| |
线程参数及顺序
- 线程中传递参数有三种方法
- 1.使用元组传递
threading.Thread(target=fun_name,args=(参数。。。))thread_1 = threading.Thread(target=loop0, args=(10, 21, 22)) - 2.使用字典传递
threading.Thread(target=fun_name,kwargs={"参数名": "参数值"....})thread_1 = threading.Thread(target=loop0, kwargs={"a": 10, "b": 21, "c": 22}) - 3.混合使用元组和字典传递
threading.Thread(target=fun_name,args=(10, 21, 22), kwargs={"参数名": "参数值"....})thread_1 = threading.Thread(target=loop0, args=(10, 21), kwargs={"c": 22})
- 1.使用元组传递
| |
守护线程
- 守护线程:如果在程序中将子线程设置为守护线程,则该子线程会在主线程结束时自动退出,设置方式为
threaj.setDaemon(True),要在thread.start0之前设置,默认是false的,也就是主线程结束时,子线程依然在执行。 - 对于python应用我们都知道
main方法是入口,它的运行代表着主线程开始工作了,我们都知道Python虚拟机里面有垃圾回收器的存在使得我们放心让main运行,然而这背后是垃圾回收线程作为守护着主线程的守护线程。
| |
并行和并发
- 多任务的原理剖析
- 操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒…….这样反复执行下去。
- 表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。

- 并发:指的是任务数多于cpu核数,通过操作系统的各种任务调度算法,实现用多个任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一超执行而已)
- 真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。
- 并发:任务数量大于CPU的核心数

- 并行:指的是任务数小于等于cpu核数,即任务真的是一起执行的
- 并行:任务数量小于或等于CPU的核心数

多线程——共享全局变量
- 当多个线程修改同一个资源的时候,会出现资源竞争,导致计算结果有误
- 调用
join方法优先让某个线程先执行- 缺点:将多线程变成了单线程,影响执行效率
| |
同步和异步
- 同步:多任务,多个任务之间执行的时候要求有先后顺序,必须一个先执行完成之后,另一个才能继续执行,只有一个主线。如:你说完,我再说(同一时间只能做一件事情)
- 异步,指的是:多个任务之间执行没有先后顺序,可以同时运行,执行的先后顺序不会有什么影响,存在的多条运行主线。如:发微信(可以不用等对方回复,继续发)、点外卖(点了外卖后,可以继续忙其他的事情,而不是坐等外卖,啥也不做)
线程锁

互斥锁
- 当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制线程同步能够保证多个线程安全访问竞争源,最简单的同步机制是引入互斥锁。
- 互斥锁为资源引入一个状态:锁定/非锁定
- 某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。
- 互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
| |
死锁
- 在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
- 注意:使用完毕及时释放

| |