多进程编程
参考代码:
https://github.com/FLBa9762/Mutli_Process.git
基本概念
并行: 对于多核CPU处理多任务,操作系统会给每个CPU的每个内核安排一个执行的任务,多核CPU并行地执行多任务。
进程(Process):进程是资源分配的最小单位,是操作系统进行资源分配和调度运行的基本单位。
进程基本操作
创建进程
创建了名为task1和task2的进程,进程调用的是process1和process2函数(demo1.py)
task1 = multiprocessing .Process(target=process1)
task2 = multiprocessing .Process(target=process2)
开始进程
开始执行两个进程(demo1.py)
task1.start()
task2.start()
等待进程结束
等待进程结束后代码再往下走(demo1.py)
task1.join()
task2.join()
为进程函数传递参数
可以传递args和kwargs,一般不使用字典传递,这里只介绍args传递方法,传递的实参是函数process1的参数(demo2.py)
注意要以元组的方式传递,元组只有单个元素时要加一个逗号 “,” 。
task1 = multiprocessing .Process(target=process1, args=(100000,))
task2 = multiprocessing .Process(target=process2, args=(100000,))
获取进程id
需要导入os模块,用os模块的**os.getpid()**函数获取进程的编号。(demo2.py)
def process1(num):
multi1 = test_code(num)
print("process1:{}".format(os.getpid()))
获取父进程id,使用 os.getppid() 函数。
def process1(num):
multi1 = test_code(num)
print("process1:{}".format(os.getppid()))
一个多进程程序中的父进程和子进程关系:(demo2.py)
import multiprocessing
import time
import os
#子进程
def process1(num):
print("process1:{}".format(os.getppid()))
#子进程
def process2(num):
print("process2:{}".format(os.getppid()))
#父进程
def run():
print("run:{}".format(os.getpid()))
task1 = multiprocessing .Process(target=process1, args=(100000,))
task2 = multiprocessing .Process(target=process2, args=(100000,))
task1.start()
task2.start()
#父进程
if __name__ == '__main__':
print("main:{}".format(os.getpid()))
run()
以上代码运行出四个进程的id相同:
main:22564
run:22564
process1:22564
process2:22564
进程之间不共享全局变量
每个进程修改全局变量后只能局部可见,虽然使用相同的名字,但是全局变量不共享,以下代码可验证:(demo3.py)
import multiprocessing
import time
global_list = []
def send_function():
for i in range(3):
global_list.append(i)
print("send_data:{}".format(global_list))
def receive_function():
print("receive_data:{}".format(global_list))
if __name__ == '__main__':
send = multiprocessing.Process(target=send_function)
receive = multiprocessing.Process(target=receive_function)
send.start()
time.sleep(1) # 等待 send_function() 修改完全局变量后再读取
receive.start()
以上代码得到结果如下,可以验证进程之间确实不共享全局变量
send_data:[0, 1, 2]
receive_data:[]
主进程会等待所有子进程结束后再结束
设置保护主进程
设置子进程属性 daemon 为 True 来使主进程运行完毕后子进程强制结束:(demo4.py)
import multiprocessing
import time
def work():
for i in range(10):
print("working!")
time.sleep(0.2)
if __name__ == '__main__':
process = multiprocessing.Process(target=work)
process.daemon = True
process.start()
time.sleep(1)
# process.terminate()
print("主进程完毕!")
如果不设置,则主进程先运行完毕后子进程还要继续运行,知道打印10个working在结束
设置了 process.daemon = True 后,主进程执行完毕后直接终止子进程,打印结果如下:
working!
working!
working!
working!
working!
主进程完毕!
或者使用:
process.terminate() #手动结束子进程
也可以做到相同效果