1、创建进程
方法1:使用fork()
import os
pid = os.fork()
if pid ==0: # 子进程
print("child")
else: # 父进程
print("parent")
方法2:使用multiprocessing.Process
from multiprocessing import Process
import os
def run_proc(args):
print("子进程运行中,args = %s,pid = %d " %(args,os.getpid()))
if __name__=='__main__':
print("父进程运行中,pid = %d " % (os.getpid()))
p = Process(target=run_proc,args = ('Test',))
# p.is_alive() # 判断进程是否正在存活
# p.terminate() # 不管任务是否完成,直接终止
print("--- 子进程开始执行 ---")
p.start()
p.join() # 使主进程等待子进程执行完后才退出
print("--- 子进程结束执行 ---")
方法3:继承multiprocessing.Process类
from multiprocessing import Process
class MyProcess(Process):
def run(self): # 重写了run()方法
print("---子类---")
if __name__=='__main__':
p = MyProcess()
p.start() # start调用了run()方法
p.join()
2、进程池
先创建好很多进程,将这些进程放入进程池中,当进程被使用时再分配。而不是在使用时在创建。
# 说明: 一般情况下,主进程用来等待,真正的任务在子进程中执行
from multiprocessing import Pool
import os,time
def worker(num): # 任务
for i in range(5):
print("---pid = %d, num = %d---" %(os.getpid(),num))
time.sleep(1)
po = Pool(3)
for i in range(10):
print("---%d---" %i)
po.apply_async(worker,(i,)) # [非阻塞方式] 向进程池中添加任务worker,以及参数(i,)
# po.apply(worker, (i,)) # [阻塞方式] 添加任务
print("---start---")
po.close() # 关闭进程池,相当于不能再添加新任务
po.join() # 主进程
print("---end---")
3、进程间通信Queue
进程通信有多种方式:管道、消息队列、socket等,本文只介绍Queue
from multiprocessing import Queue
q = Queue(3) # 初始化一个Queue对象,该对象最多可以接受3条消息
q.put("message 1")
q.put_nowait("message 2")
q.get() # 阻塞
q.get_nowait() # 不阻塞
if not q.full(): # 先判断消息队列是否满,再写入
if not q.empty(): # 先判断消息队列是否空,再读取
进程池使用Queue
from multiprocessing import Manager,Queue,Pool
q = Manager().Queue() # 必须使用该方式创建Queue()
po = Pool(3)
po.apply(writefunc,(q,)) # 向进程池中添加任务
po.apply(readfunc,(q,)) # 向进程池中添加任务
4、异步
同步:你喊你朋友吃饭,你朋友在忙,你就一直等着,等你朋友忙完了,一起去吃饭
异步:你喊你朋友吃饭,你朋友在忙,你就说等你忙完了叫我一下,我先去干自己的货去了;当你朋友忙完了,然后告诉你,最后一起去吃饭
from multiprocessing import Pool
import time
import os
def test1():
print("pid=%d,ppid=%d" %(os.getpid(),os.getppid()))
time.sleep(2)
return "OK"
def test2(args):
print("-----call back---,pid=%d" %os.getppid())
print("-----call back---,args=%d" % args)
pool = Pool(3) #进程池中有3个进程,等待执行任务
pool.apply_async(func=test1, callback=test2) # 添加一个任务到进程池中
# 1、先执行test1任务;
# 2、当test1任务完成后,主进程任务将被打断,执行test2任务(test1任务的返回值作为实参传递给test2函数的形参)
# 3、当test2任务完成后,主进程任务继续执行
# 主进程任务
while True:
time.sleep(1)
print("---主进程%d再执行---" %os.getpid())