Python 多进程
进程的创建-multiprocessing
multiprocessing模块就是跨平台版本的多进程模块,提供了一个Process类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情
# coding=utf-8 import os from multiprocessing import Process class RunProcess(Process): def run(self): print(f"i am a subprocess, my name is {self.name}") print(f"subprocess id is {os.getpid()}") print(f"spid is {os.getppid()}") if __name__ == '__main__': print(f"process id is {os.getpid()}") proc = RunProcess() proc.start()
Process创建的实例对象的常用方法与属性
常用方法:
- start():启动子进程实例(创建子进程)
- is_alive():判断进程子进程是否还在活着
- join([timeout]):等待子进程执行结束,或等待多少秒
- terminate():不管任务是否完成,立即终止子进程
常用属性:
- name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
- pid:当前进程的pid(进程号)
# coding=utf-8 import os import time from multiprocessing import Process class RunProcess(Process): def run(self): print(f"i am a subprocess, my name is {self.name}") print(f"subprocess id is {os.getpid()}") print(f"spid is {os.getppid()}") time.sleep(3) if __name__ == '__main__': print(f"process id is {os.getpid()}") proc = RunProcess() proc.start() proc.join() print("end...")
进程间不共享全局变量
# -*- coding:utf-8 -*- from multiprocessing import Process import os import time nums = [11, 22] class WorkOne(Process): def run(self): print("in process pid=%d ,nums=%s" % (os.getpid(), nums)) for i in range(3): nums.append(i) time.sleep(1) print("in process pid=%d ,nums=%s" % (os.getpid(), nums)) if __name__ == '__main__': p1 = WorkOne() p1.start() p1.join() p2 = WorkOne() p2.start()
运行结果:
in process pid=23596 ,nums=[11, 22] in process pid=23596 ,nums=[11, 22, 0] in process pid=23596 ,nums=[11, 22, 0, 1] in process pid=23596 ,nums=[11, 22, 0, 1, 2] in process pid=21940 ,nums=[11, 22] in process pid=21940 ,nums=[11, 22, 0] in process pid=21940 ,nums=[11, 22, 0, 1] in process pid=21940 ,nums=[11, 22, 0, 1, 2]
进程间通信
使用 multiprocessing 模块的 Queue 这个类来实现进程间的数据传递,Queue 本身是一个消息队列程序
Queue 对象的方法:
- q = Queue(),若括号中没有指定最大可接收的消息数量,那么表示可接受的消息数量没有上限(生产环境一定需要指定大小)
- q.qsize():返回当前队列包含的消息数量
- q.empty():判断队列是否为空,是返回 True,反之 False
- q.full():判断队列是否填满,是返回 True,反之 False
- q.get(block=, timeout=):获取队列中的一条消息,然后将其从队列中移除,block 默认为 True(阻塞),timeout 默认为一直等待,所以默认会直到取到一条消息为止,如果设置了 timeout,则会等待 n 秒,若还没有取到数据,则抛出 Queue.Empty 异常;如果 block 为 False,消息队列一旦为空,则立即抛出 Queue.Empty 异常
- q.get_nowait():相当于 q.get(block=False)
- q.put(item, block=, timeout=):将 item 消息写入队列,block 默认值为 True(阻塞),timeout 默认为一直等待,所以默认会停在写入状态,直到消息写入为止,如果设置了 timeout,则会等待 n 秒,若还没有空间写入,则会抛出 Queue.Full 异常;如果 block 为 False,消息队列一旦没有空间可写入,则立即抛出 Queue.Full 异常
- q.put_nowait(item):相当于 q.put(item, block=False)
from multiprocessing import Process, Queue import os, time, random # 写数据进程执行的代码: def write(q): for value in ['A', 'B', 'C']: print('Put %s to queue...' % value) q.put(value) time.sleep(random.random()) # 读数据进程执行的代码: def read(q): while True: if not q.empty(): value = q.get(True) print('Get %s from queue.' % value) time.sleep(random.random()) else: break if __name__=='__main__': # 父进程创建Queue,并传给各个子进程: q = Queue() pw = Process(target=write, args=(q,)) pr = Process(target=read, args=(q,)) # 启动子进程pw,写入: pw.start() # 等待pw结束: pw.join() # 启动子进程pr,读取: pr.start() pr.join() # pr进程里是死循环,无法等待其结束,只能强行终止: print('') print('所有数据都写入并且读完')
每天都要遇到更好的自己.