Python 多进程通信-Queue

📌 1️⃣ 多进程是否共享数据?

在 Python 中,每个进程有独立的内存空间默认不共享全局变量

🎯 示例:子进程修改全局变量不会影响主进程

a = 100
进程A:a+=30
进程B: a-=50
a?
from multiprocessing import Process
import os

a = 100

def add():
    global a
    a += 30
    print(f"子进程1中 a = {a}")

def sub():
    global a
    a -= 50
    print(f"子进程2中 a = {a}")

if __name__ == '__main__':
    print(f"主进程开始 a = {a}")
    p1 = Process(target=add)
    p2 = Process(target=sub)

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    print(f"主进程结束 a = {a}")  # 仍为 100,不受子进程影响
----
主进程开始 a = 100
子进程1中 a = 130
子进程2中 a = 50
主进程结束 a = 100

📌 输出说明:

  • 每个进程复制了主进程中的数据副本

  • 子进程对变量 a 的修改,只在各自进程内生效。

  • 主进程的 a 保持不变。


🔄 2️⃣ 多进程通信:使用 Queue

Python 提供 multiprocessing.Queue 实现多进程间通信,遵循先进先出(FIFO)。

✅ 创建队列

from multiprocessing import Queue

q = Queue(3)  # 最多可放3条消息

✅ 常用方法汇总

方法 说明
q.put(item) 添加数据(阻塞)
q.put_nowait(item) 非阻塞添加(满则抛异常)
q.get() 获取数据(阻塞)
q.get_nowait() 非阻塞获取(空则抛异常)
q.empty() 队列是否为空
q.full() 队列是否已满
q.qsize() 队列当前消息数量

💬 3️⃣ 队列入队 & 出队示例

from multiprocessing import Queue

if __name__ == '__main__':
    q = Queue(3)
    q.put('Python')
    q.put('is')
    q.put('fun')
    print('队列中的消息数量:',q.qsize()) #  3
    print('队列是否已满:', q.full())  # True

    print(q.get())  # Python
    print(q.get())  # is
    print(q.get())  # fun
    print('队列是否为空:', q.empty())  # True

💥 4️⃣ 向满队列添加(超时等待)

from multiprocessing import Queue

if __name__ == '__main__':
    q = Queue(3)
    q.put('A')
    q.put('B')
    q.put('C')

    q.put('D', timeout=3)  # 等待3秒,如果还满则抛 queue.Full 异常

🤝 5️⃣ 使用队列实现进程间通信

🎯 示例:一个进程写数据,另一个读取

from multiprocessing import Queue,Process
import time


a=100
def write_msg(q): # q队列
    global a
    if not q.full():
        for i in range(6):
            a-=10
            q.put(a) # 入队
            print('a入队时的值:',a)
# 出队
def read_msg(q):
    time.sleep(1)
    while not q.empty():
        print('出队时a的值:',q.get())

if __name__ == '__main__':
    print('主进程开始运行')
    q=Queue() # 没有指定参数,接收消息没有上限
    # 创建两个进程
    p1=Process(target=write_msg(q),args=(q,))
    p2=Process(target=read_msg(q),args=(q,))
    #启动子进程
    p1.start()
    p2.start()

    p1.join()
    p2.join()

    print('主进程运行结束')
----
主进程开始运行
a入队时的值: 90
a入队时的值: 80
a入队时的值: 70
a入队时的值: 60
a入队时的值: 50
a入队时的值: 40
出队时a的值: 90
出队时a的值: 80
出队时a的值: 70
出队时a的值: 60
出队时a的值: 50
出队时a的值: 40
主进程运行结束

📌 说明

  • 队列 q 作为中介在两个进程间传递消息。

  • 写进程负责生产数据读进程消费数据,避免共享变量带来的问题。


✅ 小结:进程间通信重点

关键点 说明
全局变量是否共享? ❌ 不共享,进程有独立内存
通信方式 ✅ 使用 multiprocessing.Queue
队列优势 安全、先进先出、支持多进程共享
错误示例 忽视 .start() 方式或 target=func() 写法错(应是 target=func

posted @ 2025-05-05 16:19  kyle_7Qc  阅读(83)  评论(0)    收藏  举报