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 对象的方法:

  1. q = Queue(),若括号中没有指定最大可接收的消息数量,那么表示可接受的消息数量没有上限(生产环境一定需要指定大小)
  2. q.qsize():返回当前队列包含的消息数量
  3. q.empty():判断队列是否为空,是返回 True,反之 False
  4. q.full():判断队列是否填满,是返回 True,反之 False
  5. q.get(block=,  timeout=):获取队列中的一条消息,然后将其从队列中移除,block 默认为 True(阻塞),timeout 默认为一直等待,所以默认会直到取到一条消息为止,如果设置了 timeout,则会等待 n 秒,若还没有取到数据,则抛出 Queue.Empty 异常;如果 block 为 False,消息队列一旦为空,则立即抛出 Queue.Empty 异常
  6. q.get_nowait():相当于 q.get(block=False)
  7. q.put(item, block=, timeout=):将 item 消息写入队列,block 默认值为 True(阻塞),timeout 默认为一直等待,所以默认会停在写入状态,直到消息写入为止,如果设置了 timeout,则会等待 n 秒,若还没有空间写入,则会抛出 Queue.Full 异常;如果 block 为 False,消息队列一旦没有空间可写入,则立即抛出 Queue.Full 异常
  8. 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('所有数据都写入并且读完')
每天都要遇到更好的自己.
原文地址:https://www.cnblogs.com/kaichenkai/p/10857283.html