各个进程是完全独立的, 肯定需要通信, multiprocessing包支持进程间通信(IPC, Inter-Process Communication)有两种方式: 管道(Pipe)和队列(Queue).

这两种方式都是使用消息传递实现的.


使用Queue实现IPC

from multiprocessing import Process, Queue
import os, time, random


def write(q):
    print("负责写的进程:", os.getpid())
    for c in "你好志玲姐姐":
        q.put(c)  # 向队列中添加数据
        time.sleep(random.random())  # 随机休眠


def read(q):
    print("负责读的进程:", os.getpid())
    while True:
        print("读到的数据:", q.get())  # 从队列中读取数据


if __name__ == "__main__":
    q = Queue()  # 创建一个用于进程间通信的队列
    pWrite = Process(target=write, args=(q,))  # 创建写的进程
    pRead = Process(target=read, args=(q,))  # 创建读的进程
    pWrite.start()
    pRead.start()

    pWrite.join()
    print("负责写的进程结束!")
    pRead.terminate()  # 因为读的进程内部是死循环, 只能通过这种方式结束
    print("所有的进程结束!")


Queue

Queue用来进程间通信.

Queue([maxsize]) 创建共享的进程队列. maxsize是允许的最大项目数. 如果省略此参数, 则无大小限制.

Queue实例对象的一些常用方法:

1. q.close()

关闭队列, 防止向队列中加入更多数据

2. q.empty()

如果调用此方法时q为空, 则返回True. 如果有其他进程正在向q中添加或删除数据,则结果是不可靠的.

3. q.full()

如果q已满, 则返回True. 结果也是不可靠的.

4. q.get([block, timeout])

从队列中读取数据. 如果队列为空, 则此方法会阻塞. block是个布尔值, 用来决定是否阻塞, 默认是True, 表示为空时阻塞. 如果设置为False,则在q为空时抛出异常Queue.Empty

5. q.put(item[, block, timeout)

向队列中添加数据.

6. q.qsize()

返回队列中目前项目的数量. 结果也是不可靠的.


使用pipe实现IPC

from multiprocessing import Process, Pipe
import os, time, random


def write(p):
    print("负责写的进程:", os.getpid())
    for c in "你好志玲姐姐":
        p.send(c)
        time.sleep(random.random())


def read(p):
    print("负责读的进程:", os.getpid())
    while True:
        c = p.recv()
        print("接收到的数据", c)


if __name__ == "__main__":
    (input_p, output_p) = Pipe()    #   创建一个管道, 返回的是一个元组:默认情况下管道是双向的
    pWrite = Process(target=write, args=(output_p,))  # 创建写的进程
    pRead = Process(target=read, args=(input_p,))  # 创建读的进程
    pWrite.start()
    pRead.start()

    pWrite.join()
    print("负责写的进程结束!")
    pRead.terminate()  # 因为读的进程内部是死循环, 只能通过这种方式结束
    print("所有的进程结束!")


Pipe()

Pipe([duplex]), 在进程间创建一条管道.

返回一个元组(conn1, conn2), 其中conn1, conn2表示管道两端的Connection对象. 默认情况下, 管道是双向的.

如果duplex设置为False, conn1值能用于接收, 而conn2只能用于发送.

Connection对象具有如下方法:

1. c.close()

关闭连接. 如果c被垃圾收集, 将自动调用此方法

2. c.poll([timeout])

如果连接上的数据可以用, 返回True

3. c.recv()

接收管道中的数据. 如果连接的另一端已经关闭, 再也不存在任何数据, 将引发EOFError异常

4. c.send(obj)

通过连接发送数据. obj是与序列号兼容的任意对象.

Copyright © 李振超 2018 all right reserved,powered by Gitbook
该文件最后修订时间: 2018-02-25 07:12:09

results matching ""

    No results matching ""