1、进程的意义
-
是操作系统进行资源分配的最小单位
-
是实现多任务的一种方式
2、多进程创建
方法一(直接创建):
-
创建进程
进程对象 = multiprocessing.Process(target=func)
-
主进程中执行子进程
进程对象.start()
示例
import multiprocessing
import time
def pro01():
for i in range(3):
print("子进程01")
time.sleep(1)
def pro02():
for i in range(3):
print("子进程02")
time.sleep(1)
if __name__ == '__main__':
# target:指定函数名
process01 = multiprocessing.Process(target=pro01)
process02 = multiprocessing.Process(target=pro02)
process01.start()
process02.start()
输出
方法二(继承类):
继承Process
来自定义进程类,重写run
方法
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self, name):
super(MyProcess, self).__init__()
self.name = name
def run(self):
print('process name :' + str(self.name))
time.sleep(1)
if __name__ == '__main__':
for i in range(3):
p = MyProcess(str(i))
p.start()
3、获取进程编号
-
获取当前任务ID
os.getpid()
-
获取父进程ID
os.getppid()
示例
import multiprocessing
import os
import time
def pro01():
for i in range(3):
print("子进程01:当前进程ID:{}".format(os.getpid()))
print("子进程01:父进程ID:{}".format(os.getppid()))
time.sleep(1)
def pro02():
for i in range(3):
print("子进程02:当前进程ID:{}".format(os.getpid()))
print("子进程02:父进程ID:{}".format(os.getppid()))
time.sleep(1)
if __name__ == '__main__':
# target:指定函数名
process01 = multiprocessing.Process(target=pro01)
process02 = multiprocessing.Process(target=pro02)
process01.start()
process02.start()
输出
4、给进程传递参数
-
args:以元组的方式给执行任务传参
进程对象 = multiprocessing.Process(target=func, args=(value, ))
此处注意,若只有一个元素,那个逗号也是不可以省略的。
-
kwargs:以字典方式给执行任务传参
进程对象 = multiprocessing.Process(target=func,kwargs={"变量名": 变量值})
-
其他
进程对象 = multiprocessing.Process(target=func(value, ))
进程对象 = multiprocessing.Process(target=func(keys=value, ))
示例
import multiprocessing
import time
def pro01(name, age):
for i in range(10):
print('我是子进程01')
time.sleep(0.5)
if __name__ == '__main__':
# args
process01 = multiprocessing.Process(target=pro01, args=('yy', 21))
# kwargs
process02 = multiprocessing.Process(target=pro01, kwargs={'name': 'yy', "age": 21})
process03 = multiprocessing.Process(target=pro01, kwargs={"age": 21, 'name': 'yy'})
# 直接传参
process04 = multiprocessing.Process(target=pro01('yy', 21))
process05 = multiprocessing.Process(target=pro01(name='yy', age=21))
5、主进程守护
一般情况下,不加干涉的,主进程会等待所有的子进程执行结束再结束
import multiprocessing
import time
def pro():
for i in range(10):
print('我是子进程01')
time.sleep(0.5)
if __name__ == '__main__':
process = multiprocessing.Process(target=pro)
process.start()
time.sleep(1)
print("我是主进程")
输出
因此我们需要对子进程加以限制,当主进程结束时,子进程也不再继续执行,直接结束
从而达到对主进程的守护
-
守护
进程对象.demon = True
守护应当放在创建进程之后,执行之前
当主进程执行后,再销毁子进程,因此子进程可能会先执行若干部分
import multiprocessing
import time
def pro():
for i in range(10):
print('我是子进程01')
time.sleep(0.5)
if __name__ == '__main__':
process = multiprocessing.Process(target=pro)
# 设置进程守护
process.daemon = True
process.start()
time.sleep(1)
print("我是主进程")
输出
-
销毁
进程对象.terminate()
销毁应当放在执行之后
直接销毁子进程,执行主进程
import multiprocessing
import time
def pro():
for i in range(10):
print('我是子进程01')
time.sleep(0.5)
if __name__ == '__main__':
process = multiprocessing.Process(target=pro)
process.start()
#直接销毁
process.terminate()
time.sleep(1)
print("我是主进程")
输出
6、进程阻塞
进程对象.start()
进程对象.join()
等待当前子进程完成后,再执行其他子进程或者主进程
import multiprocessing
import os
import time
def pro01():
for i in range(3):
print("子进程01:当前进程ID:{}".format(os.getpid()))
print("子进程01:父进程ID:{}".format(os.getppid()))
time.sleep(1)
def pro02():
for i in range(3):
print("子进程02:当前进程ID:{}".format(os.getpid()))
print("子进程02:父进程ID:{}".format(os.getppid()))
time.sleep(1)
if __name__ == '__main__':
# target:指定函数名
process01 = multiprocessing.Process(target=pro01)
process02 = multiprocessing.Process(target=pro02)
process01.start()
process01.join()
process02.start()
输出
7、进程池
创建多个进程,我们不需要一个个去创建,我们可以使用Pool
模块来完成
进程池名称 = multiprocessing.Pool(processes=num) #创建进程池
进程池名称.apply() #执行进程池
进程池名称.apply_async()
进程池名称.close() #关闭进程池
进程池名称.join() #进程阻塞
其他方法:
方法 | 含义 |
---|---|
apply() | 同步执行(串行) |
apply_async() | 异步执行(并行) |
terminate() | 立刻关闭进程池 |
join() | 主进程等待所有子进程执行完毕。必须在close或terminate()之后使用 |
close() | 等待所有进程结束后,才关闭进程池 |
import multiprocessing
import time
def func(msg):
print("msg:", msg)
time.sleep(3)
print("end")
if __name__ == "__main__":
# 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
pool = multiprocessing.Pool(processes=3)
for i in range(5):
msg = "hello %d" % i
# 非阻塞式,子进程不影响主进程的执行,会直接运行到 pool.join()
# pool.apply_async(func, (msg,))
# 阻塞式,先执行完子进程,再执行主进程
pool.apply(func, (msg, ))
print("Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~")
# 调用join之前,先调用close函数,否则会出错。
pool.close()
# 执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
pool.join()
print("Sub-process(es) done.")
左(非阻塞,速度快) 右(阻塞式,速度慢)