mark一下学习笔记:
1.多任务:
学习python多线程与多进程之前,需要先知道多任务这个概念。多任务即是同一时间让系统执行多个任务,其中包括并发和并行两种方式。
A.并发
如上图所示,假设应用场景下只有单核的CPU,需要同时处理3个任务。这就是并发,单核CPU在开启任务1之后会立马开启任务2,任务3也同理。这种在一段时间内交替执行任务的方式就成为并发。此外,单核CPU下只会存在并发,不存在并行的情况。
B.并行
并行就是在同一时刻一起执行多个任务。上图就是多核CPU,每个CPU核执行1个任务的例子。其中任务数 <= CPU核数,即可以进行并行的多任务执行方式。
2.多进程:
A.进程概念
进程是操作系统中进行资源分配和调度的最小单位,也就是基本单位。一个正在运行的程序就是一个进程,一个程序运行至少需要一个进程来进行资源分配和调度。
如上图所示,假设现在有一个main.py文件,里面写了fun_a和fun_b两个函数。我们要在文件里执行这两个函数,就可以按照单进程和多进程的方式去执行,其中多进程的情况下,主线程会开启一个子进程去并发的执行这两个函数。因此,效率更高!
B.进程创建
包含3个步骤:
1.导入进程包 import multiprocessing
2.进程类创建进程对象 multiprocessing.Process(target=任务名,name=进程名, group=进程组)
3.启动进程执行任务 .start()
示例代码:
import multiprocessing
import time
#定义两个间隔0.5s执行3次的函数
def fun_a():
for i in range(3):
print("f_a()")
time.sleep(0.5)
def fun_b():
for i in range(3):
print("f_b()")
time.sleep(0.5)
1.顺序执行:
if __name__ == "__main__":
fun_a()
fun_b()
运行结果:可以看出两个函数是按照先后顺序执行的
2.多进程运行:
if __name__ == "__main__":
#使用进程类创建进程对象
fun_a_process = multiprocessing.Process(target=fun_a)
fun_b_process = multiprocessing.Process(target=fun_b)
#启动多进程执行任务
fun_a_process.start()
fun_b_process.start()
运行结果:可以看出两个函数是同时执行的
C.多进程带参数任务
上面我们使用多进程执行的fun_a()和fun_b()两个函数都是无参的。对于有参的函数,我们可以在线程类创建线程对象的时候,借用python特有的args, kwargs传入multiprocessing.Process(),其中args是传入元组,kwargs是出入字典形式。
首先我们定义两个带参数的fun_a和fun_b
import multiprocessing
import time
#定义两带参数的函数
def fun_a(num, name):
for i in range(num):
print(name)
time.sleep(0.5)
def fun_b(num):
for i in range(num):
print("f_b()")
time.sleep(0.5)
1.args传参:按顺序传参,参数只有一个的时候,要记得按照元组的形式(3, )
if __name__ == "__main__":
#使用进程类闯进进程对象
fun_a_process = multiprocessing.Process(target=fun_a, args=(3, "fun_a()"))
fun_b_process = multiprocessing.Process(target=fun_b, args=(3, ))
#启动多进程执行任务
fun_a_process.start()
fun_b_process.start()
运行结果:
2.kwargs传参:keys名对应上即可
if __name__ == "__main__":
#使用进程类创建进程对象
fun_a_process = multiprocessing.Process(target=fun_a, kwargs={
"num":4, "name":"fun_a()"})
fun_b_process = multiprocessing.Process(target=fun_b, kwargs={
"num":3})
#启动多进程执行任务
fun_a_process.start()
fun_b_process.start()
运行结果:
D.类继承的方式
由于fun_a和fun_b两个函数功能相近,如果不想重复定义多个相似功能的函数,可以采用类继承的方式实现与上面相同的效果
import time
from multiprocessing import Process
#继承Process类
class fun_(Process):
def __init__(self, name, num):
super().__init__()
self.name = name
self.num = num
#重写run函数
def run(self):
for i in range(self.num):
print(self.name)
time.sleep(0.5)
if __name__ == "__main__":
print("start")
for para in [["fun_a",3], ["fun_b", 4]]:
fun_(para[0], para[1]).start()
运行结果:
E.其他
获取进程编号:
1.获取当前进程编号:os.getpid()
2.获取当前父进程编号:os.getppid()
设置守护主进程:
1.主进程默认情况下会等到所有子进程结束才结束
2.设置 work_process.daemon = True,则主进程结束,子进程都会结束