Python多进程(二)

本文介绍了Python中实现多进程通信的三种方式:Queue队列、Pool进程池和Pipe管道。通过Queue实现进程间的数据交换,Pool用于管理和调度多个进程,Pipe则提供了双向通信的通道。示例代码详细展示了如何使用这些工具进行并发处理,包括任务分配、数据传输和进程同步。
摘要由CSDN通过智能技术生成

python多进程(二)

代码地址:https://github.com/FLBa9762/Mutli_Process.git

Queue队列实现多进程的通信(demo5.py)

创建Queue队列

创建了一个长度为3的队列,最多可以存放三个数据

from multiprocessing import Queue

QUE = Queue(3)

添加数据

使用Queue类的put()方法

QUE.put("message1")

获取数据

使用Queue类的get()方法, 先放先取

QUE.get()

判断队列是满还是空

返回值为bool类型

QUE.full()
QUE.empty()

一个进程通信例子

此例子中,接收进程会一直等待发送进程发送给Queue数据
注:没有添加接收进程的停止判断

from multiprocessing import Queue
import multiprocessing
import numpy as np
import time


def episode(q):
    data = np.arange(1, 11)
    for i in data:
        q.put(i)


def send_message(q):
    for epi in range(10):
        print("episode: {}".format(epi))
        episode(q)
        time.sleep(3)
    print("send_done! ")


def receive_message(q):
    receiver = []
    i = 0
    while True:
        rec = q.get()
        receiver.append(rec)
        print("receive: {}".format(i))
        i += 1


def run():
    q = Queue(20)
    print(q.qsize())
    process1 = multiprocessing.Process(target=send_message, args=(q,))
    process2 = multiprocessing.Process(target=receive_message, args=(q,))
    process1.start()
    # process1.join()
    process2.start()


if __name__ == '__main__':
    run()

进程池Pool(demo6.py)

设置进程池最大数量

设置最大进程数为3,但是还未创建,在使用时候创建

from multiprocessing import Pool

po = Pool(processes=3)

进程池添加任务

用Pool类的apply_async()方法, send_message是任务函数对象,(i,)是send_message()元组形式的参数

	po.apply_async(send_message, (i,))

进程池管理

Pool进程池使用时需要手动添加一些管理,否则不能顺利执行完所有任务

	po.close()  # 关闭进程池,使其不接收新的任务
	po.join()  # 等待进程池里的任务结束,主进程再退出

python为进程池设置了使用规则,进程池创建完成、分配好任务之后,需要执行po.close()手动关闭进程池才能正常运行,如果不关闭就会报错

Traceback (most recent call last):
  File "C:/Users/fusion007/Desktop/Mutli_Process-main/demo6.py", line 36, in <module>
    po.join()  # 等待进程池里的任务结束,主进程再退出
  File "D:\Anaconda3\lib\multiprocessing\pool.py", line 553, in join
    raise ValueError("Pool is still running")
ValueError: Pool is still running

po.join()的用法和之前的Process.join()相近,就是让主进程等待进程池任务结束后再退出。

Pool进程池例子

from multiprocessing import Pool
import time
import os
import random


def send_message(msg):
    t_start = time.time()
    print("{} 开始执行,进程编号为 {}".format(msg, os.getpid()))
    # time.sleep(0.11)
    time.sleep(random.random()*2)
    t_stop = time.time()
    print('{} 执行完毕, 用时 {} '.format(msg, t_stop - t_start))


if __name__ == '__main__':
    po = Pool(processes=3)
    for i in range(0, 10):
        po.apply_async(send_message, (i,))

    print("----------start------------     {}".format(os.getpid()))
    # po.close()  # 关闭进程池,使其不接收新的任务
    po.join()  # 等待进程池里的任务结束,主进程再退出
    print("-----------end-------------")

Pipe管道使用(demo7.py)

创建一个Pipe管道

创建管道连接, 设置参数 duplex 为True表示管道是全双工模式的,返回值 conn_1 和 conn_2 分别是管道的两端。

import multiprocessing
conn_1, conn_2 = multiprocessing.Pipe(duplex=True)

为进程分配使用的管道

将管道两端作为参数传入进程的任务中,再从任务中执行收、发等工作

    p1 = multiprocessing.Process(target=send_message, args=(conn_1,))
    p2 = multiprocessing.Process(target=receive_message, args=(conn_2,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

p1 和 p2 两个进程的任务 send_message 和 receive_message 的代码如下:

def send_message(conn_1):
    conn_1.send("send_message!!!")
    print("conn1 send message: {}".format("send_message!!!"))
    data = conn_1.recv()
    print("ok, finish ! {}".format(data))

def receive_message(conn2):
    data = conn2.recv()
    print("conn2 receive data: {}".format(data))
    conn2.send("conn2 received message")
    print("conn2 send message:{}".format("conn2 received message"))

实验中,recv( ) 函数在执行时要等待另一个端口发送来信息才可以,否则会一直等待

关闭管道的端口

管道的 close() 函数

conn2.close()

结果

conn1发送——> conn2接受,并回复——>conn1受到回复,结束

D:\Anaconda3\python.exe C:/Users/fusion007/Desktop/Mutli_Process-main/demo8.py
conn1 send message: send_message!!!
conn2 receive data: send_message!!!
conn2 send message:conn2 received message
ok, finish ! conn2 received message
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值