一、多任务介绍
目录
1.1、多任务的优势:多任务的最大好处是充分利用CPU资源,提高程序的执行效率
2.6.1、当程序中进程的数量越来越多的时,如果没有办法区分主进程和子进程,还有不同的子进程,那么就无法有效的进程管理,为了方便管理实际上每个子进程都是有自己的编号的。
1.1、多任务的优势:多任务的最大好处是充分利用CPU资源,提高程序的执行效率
1.2、多任务的概念:多任务是指在同一时间内执行多个任务
1.3、多任务的两种表现形式:
1.3.1、并发:
在一段时间内交替去执行多个任务。对于单核CPU处理多任务,操作系统轮流让各个任务交替执行。任务数量大于CPU的核心数
1.3.2、并行:
在一段时间内真正的同时一起执行多个任务。对于多核CPU处理多任务,操作系统会给每个CPU的每个内核安排一个执行的任务,多个内核是真正的一起同时执行多个任务。多核CPU是并行的执行多任务,始终有多个任务一起执行
二、进程介绍
2.1、程序中实现多任务的方式:
在python中,想要实现多任务可以使用多进程来完成
2.2、进程的概念:
进程是资源分配的最小单位,它是操作系统进行资源分配和调度运行的基本单位,通俗理解:一个正在运行的程序就是一个进行。
2.3、进城的作用:
def func_a():
print('任务A')
def func_b():
print('任务B')
func_a()
func_b()
上述代码在执行的时候会按顺序先执行func_a,再执行func_b。如果让func_a和func_b同时执行,将会提高这个程序的效率
2.4、使用多进程完成多任务
2.4.1、进程的创建步骤
import multiprocessing #导入进程包
mul = multiprocessing.Process() #通过进程类创建进程对象;mul进程对象
mul.start() #启动进行执行任务
2.4.2、通过进程类创建进程对象需要参数
mul = multiprocessing.Process(target = clear_data)
#target:执行目标的任务名,这里指的是函数名(方法名)
#name:进程名,一般不用设置
#group:进程组,目前智能使用None
import time
import multiprocessing #导入进程包
def sing():
for i in range(0,3):
print('唱歌-{}'.format(i))
time.sleep(1)
def dance():
for i in range(0, 3):
print('跳舞-{}'.format(i))
time.sleep(1)
if __name__ == "__main__":
#单个函数执行耗时6秒,两个进程共耗时3s
sing_pro = multiprocessing.Process(target=sing)
dance_pro = multiprocessing.Process(target=dance)
sing_pro.start()
dance_pro.start()
2.5、进程执行带有参数的任务
2.5.1、进程执行带有参数的任务
参数名 | 说明 |
---|---|
args | 以元组的方式给执行任务传参 |
kwargs | 以字典方式给执行任务传参 |
sing_pro = multiprocessing.Process(target=sing,args=(3,)) #元组参数
sing_pro = multiprocessing.Process(target=dance,kwargs={"num":3}) #字段参数
元组参数需要按顺序传递,字典是根据key传参,可以不考虑顺序
2.6、获取进程编号
2.6.1、当程序中进程的数量越来越多的时,如果没有办法区分主进程和子进程,还有不同的子进程,那么就无法有效的进程管理,为了方便管理实际上每个子进程都是有自己的编号的。
2.6.2、获取进程编号的两种方式:
import os
pid = os.getpid() #获取当前进程编号
ppid = os.getppid() #获取当前父进程编号
import time
import multiprocessing
import os
def sing():
print("sing进程pid:", os.getpid()) #59401
print("sing的父进程pid:", os.getppid()) #59400
for i in range(0,3):
print('唱歌-{}'.format(i))
time.sleep(1)
def dance():
print("dance进程pid:", os.getpid()) #59402
print("dance的父进程pid:", os.getppid()) #59400
for i in range(0, 3):
print('跳舞-{}'.format(i))
time.sleep(1)
if __name__ == "__main__":
print("主进程pid:",os.getpid()) #59400
sing_pro = multiprocessing.Process(target=sing)
dance_pro = multiprocessing.Process(target=dance)
sing_pro.start()
dance_pro.start()
2.7、主进程和子进程的结束关系
默认情况下主进程会等待所有的子进程执行结束再结束
如果需要子进程跟随主进程的进度,可已经子进程设置为守护主进程,主进程结束后子进行也会结束。
dance_pro.daemon = True #dance_pro为子进程名
三、线程
进程是分配资源的最小单位,一旦创建一个进程就会分配一定的资源
线程是程序执行的最小单位,进程只负责分配资源,而利用这些资源执行程序的是线程,也就是说进程是线程的容器,一个进程中最少有一个线程来负责执行程序。同时线程不拥有系统资源,只需要一点在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。实现多任务的同时也节省了资源。
3.1、使用多线程完成多任务
3.1.1、线程的创建步骤
import threading #导入线程包
sing_th = threading.Thread(target=sing) #通过线程类创建线程对象,sing_th是线程对象
3.1.2、创建线程的参数
3.2、线程执行带有参数的任务
3.2.1、线程执行带有参数的任务
import time
import threading
def sing(num):
for i in range(num):
print('唱歌-{}'.format(i))
time.sleep(1)
def dance(count):
for i in range(count):
print('跳舞-{}'.format(i))
time.sleep(1)
if __name__ == "__main__":
sing_th = threading.Thread(target=sing,args=(2,))
dance_th = threading.Thread(target=dance,kwargs={"count":3,})
sing_th.start()
dance_th.start()
3.3、主线程和子线程的结束顺序
默认情况下主线程会等待所有的子线程执行结束再结束
如果需要子线程跟随主线程的进度,可已经子线程设置为守护主线程,主线程结束后子线程也会结束。
sing_th = threading.Thread(target=sing,daemon=True) #参数daemon=True
还可以在子线程开始执行之前设置调用setDaemon函数
sing_th.setDaemon(True)
3.4、线程之间的执行顺序
3.4.1、获取当前线程的线程对象
def task():
thred = threading.current_thread()
print(thred)
if __name__ == "__main__":
for i in range(5):
sub_thred = threading.Thread(task)
sub_thred.start()
''' 执行结果
<Thread(Thread-1, started 123145417252864)><Thread(Thread-2, started 123145422508032)>
<Thread(Thread-3, started 123145417252864)>
<Thread(Thread-4, started 123145417252864)><Thread(Thread-5, started 123145422508032)>
'''