- Linux是多用户多任务的操作系统
- 多任务的意思就是同时进行。比如,不能先站着唱完歌,再跳舞。
- 怎么同时进行呢?
答:cpu的多个核同时工作。
- 但是这就有一个问题了,现在电脑普遍四核,高端点八核。最多只能同时处理八个任务?还有我手上现在用来编程的单片机,只有一核,只能处理一个任务?
- 显然不是的。当任务数小于核心数,就是真的多任务,叫并行
- 当任务数大于核心数,就是假的多任务,叫并发
- 并发 就是某个核执行任务时,快速的切换,让我们感觉好像在一起运行一样。可能每个程序执行0.0000…1秒就切换到下一个程序了。换言之,就是切换任务的速度非常快,使我们产生了错觉。
- CPU一秒钟执行好几百万次。
- 具体每一个程序分配多久,取决于算法调度(比如优先级调度中,因为听歌之类的不希望有断断续续的感觉,所以听歌的优先级很高)。
一、多线程
- 程序是按照结构一行一行执行的,这被称为一个线程。一个程序运行起来之后,一定有一个执行代码的东西,这个东西就被称之为线程。
- 想像一个箭头,它指到哪就执行到哪。这个箭头就是一个线程,多线程就是有多个箭头。
1)对比单线程与多线程
1.单线程
- 代码如下:
- 效果如下(耗时6秒):
2.多线程
- threading模块中有一个类叫做Thread,给它的Target参数传入方法/函数/和一切可执行的操作创建出来一个实例。只要这个实例调用了start方法,就生成一个独立的线程。
import threading.Thread
......
变量名 = Thread(target=函数名)
变量名 = Thread(target=函数名)
变量名 = Thread(target=函数名)
- 代码如下:
- 效果如下(耗时1.5秒):
2)enumerate()方法
- 一个程序启动时,一定有一个线程叫做主线程。当调用模块,开启另一个线程,这个线程就叫子线程。
- 主线程没有可执行的代码时,子线程若还在,主线程会等子线程结束。
- enumerate()可以查看程序当前的线程。
len(threading.enumerate())
- enumerate函数,可以将可迭代数据的每一个元素,变为元组。当然,threading中的这个函数不是这个意思哈,只是示例。
- 看看把延时模块删除之后发生了什么,代码如下(导入模块代码变化,新增线程数量代码):
- 执行效果如下(重复执行三次,看看有何不同):
- 会发现所有线程执行没有先后顺序。说明线程的执行是看操作系统调度的(看它心情)。
- 想指定线程的先后顺序,可以使用延时
- 如果想所有子线程结束后程序就结束,可以用if加enumerate长度判断退出。
- 主线程如果先结束了,子线程必结束。
- 子线程是从调用start()开始的,可以用enumerate长度判断
3)多线程执行类
- 要通过多线程执行类,需要继承threading.Thread,调用start()时,start()会自动调用类里面的run方法。注意一个start()值生成一个线程
Class NewClass(threading.Thread):
def 函数名(self):
......
if __name__ == "__main__":
变量名 = 类名()
变量名.start()
- 代码如下:
- 结果如下:
这里没有使用延时,说明只有一个子线程。(主线程在等子线程执行完毕)
4)子线程之间使用的全局变量可以共享
- 使用一个函数修改全局变量&