前言
系列文章目录
视频及资料和课件
链接:https://pan.baidu.com/s/1LCv_qyWslwB-MYw56fjbDg?pwd=1234
提取码:1234
多任务的介绍
1 提问
利用现学知识能够让两个函数或者方法同时执行吗?
不能,因为之前所写的程序都是单任务的,也就是说一个函数或者方法执行完成另外一个函数或者方法才能执行,要想实现这种操作就需要使用多任务。
多任务的最大好处是充分利用CPU资源,提高程序的执行效率。
2 多任务的概念
多任务是指在同一时间内执行多个任务,例如: 现在电脑安装的操作系统都是多任务操作系统,可以同时运行着多个软件。
多任务效果图:
3 多任务的执行方式
- 并发
- 并行
3.1 并发
在一段时间内交替去执行任务。
例如:
对于单核cpu处理多任务,操作系统轮流让各个软件交替执行,假如:软件1执行0.01秒,切换到软件2,软件2执行0.01秒,再切换到软件3,执行0.01秒……这样反复执行下去。表面上看,每个软件都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像这些软件都在同时执行一样,这里需要注意单核cpu是并发的执行多任务的。
3.2 并行
对于多核cpu处理多任务,操作系统会给cpu的每个内核安排一个执行的软件,多个内核是真正的一起执行软件。这里需要注意多核cpu是并行的执行多任务,始终有多个软件一起执行。
并行才是多个任务真正意义一起执行。
对于多核CPU,如果执行的任务数小于CPU的核数,则并行执行;如果执行的任务数大于CPU的核数,则并发执行。
进程
1 进程的介绍
在Python程序中,想要实现多任务可以使用进程来完成,进程是实现多任务的一种方式。
2 进程的概念
一个正在运行的程序或者软件就是一个进程,进程是操作系统进行资源分配的基本单位,也就是说每启动一个进程,操作系统都会给其分配一定的运行资源(内存资源)保证进程的运行。
进程向操作系统索要内存资源,保证进程可以正常运行。真正在执行代码的是线程。
例如,将社会看成是操作系统,社会中的各种资源尤其管理,现实生活中的公司可以理解成是一个进程,公司通过向社会获取资源,从而能够向员工提供办公资源(电脑、办公桌椅等),然而在公司中真正干活的是员工,员工可以理解成线程。
注意:
一个程序运行后至少有一个进程,一个进程默认有一个线程,进程里面可以创建多个线程,线程是依附在进程里面的,没有进程就没有线程。
3 进程的作用
单进程效果图:
多进程效果图:
说明:
多进程可以完成多任务,每个进程就好比一家独立的公司,每个公司都各自在运营,每个进程各自在运行,执行各自的任务。
多进程的使用
1 导入进程包
#导入进程包 import multiprocessing
2 Process进程类的说明
Process([group [, target [, name [, args [, kwargs]]]]])
- group:指定进程组,目前只能使用None
- target:执行的目标任务名(需要执行的函数或方法的函数名或方法名)
- name:进程名字(一般不用设置,每个进程会有默认的进程名)
- args:以元组方式给执行任务传参
- kwargs:以字典方式给执行任务传参
Process创建的实例对象的常用方法
- start():启动子进程
- join():等待子进程执行结束
- terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象的常用属性
- name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
3 多进程完成多任务的代码
# 导入进程包 import multiprocessing import time # 唱歌任务 def sing(): for i in range(5): print('唱歌中...') time.sleep(0.2) # 跳舞任务 def dance(): for i in range(5): print('跳舞中...') time.sleep(0.2) # 判断当前运行的是否为主进程 if __name__ == '__main__': # 创建跳舞的子进程 dance_process = multiprocessing.Process(group=None, target=dance, name='dance') # 启动跳舞的子进程 dance_process.start() # 主进程执行唱歌的任务 sing()
注意:
执行的目标任务后面不能带(),否则相当于调用函数执行。
进程的执行顺序是无序的,具体哪个进程先执行由操作系统调度决定。
获取进程编号
1 获取进程编号的目的
获取进程编号的目的是验证主进程和子进程的关系,可以得知子进程是由那个主进程创建出来的。
获取进程编号的两种操作:
(1)获取当前进程编号
(2)获取当前父进程编号
2 获取当前进程编号
os.getpid()
表示获取当前进程编号
# 获取当前进程对象 multiprocessing.current_process()
示例代码:
# 导入进程包 import multiprocessing import time # 导入获取进程编号相关的模块 import os # 唱歌任务 def sing(): # 获取当前进程的id sing_process_id = os.getpid() # 获取当前进程对象 sing_process_object = multiprocessing.current_process() print(sing_process_object, sing_process_id) for i in range(5): print('唱歌中...') time.sleep(0.2) # 跳舞任务 def dance(): # 获取当前进程的id dance_process_id = os.getpid() # 获取当前进程对象 dance_process_object = multiprocessing.current_process() print(dance_process_object, dance_process_id) for i in range(5): print('跳舞中...') time.sleep(0.2) # 判断当前运行的是否为主进程 if __name__ == '__main__': # 获取当前进程的id main_process_id = os.getpid() # 获取当前进程对象 main_process_object = multiprocessing.current_process() print(main_process_object, main_process_id) # 创建跳舞的子进程 dance_process = multiprocessing.Process(group=None, target=dance, name='dance') # 启动跳舞的子进程 dance_process.start() # 主进程执行唱歌的任务 sing()
由于任务 sing 运行在主进程中,所以 sing 任务中获取的进程对象及进程编号与主进程相同。
主进程的进程名为 MainProcess
dance 任务的进程名为dance是由于创建进程时,由指定进程名。