【愚公系列】《Python网络爬虫从入门到精通》025-进程间通信

举报
愚公搬代码 发表于 2025/05/01 00:07:11 2025/05/01
【摘要】 标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳...
标题 详情
作者简介 愚公搬代码
头衔 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。
近期荣誉 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳博主等。
博客内容 .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
欢迎 👍点赞、✍评论、⭐收藏

🚀前言

在现代计算机系统中,进程间通信(Inter-Process Communication, IPC)扮演着至关重要的角色。随着多核处理器和分布式系统的普及,如何有效地实现不同进程之间的信息交换,已成为软件开发中的一项核心挑战。本文将深入探讨进程间通信的基本概念、常用方法和应用场景,帮助读者理解其在系统架构中的重要性。

🚀一、进程间通信

进程之间默认不共享内存,每个进程拥有独立的数据空间。若需实现进程间数据传递,需借助特殊机制。Python的multiprocessing模块提供了队列(Queue)和管道(Pipes)等方式,本节重点介绍队列。

🔎1.验证进程间无法直接共享数据

示例:全局变量在进程间的独立性

# -*- coding:utf-8 -*-
from multiprocessing import Process

def plus():
    print('-------子进程1开始------')
    global g_num
    g_num += 50
    print('g_num is %d'%g_num)
    print('-------子进程1结束------')

def minus():
    print('-------子进程2开始------')
    global g_num
    g_num -= 50
    print('g_num is %d'%g_num)
    print('-------子进程2结束------')

g_num = 100 # 定义一个全局变量
if __name__ == '__main__':
    print('-------主进程开始------')
    print('g_num is %d'%g_num)
    p1 = Process(target=plus)   # 实例化进程p1
    p2 = Process(target=minus)  # 实例化进程p2
    p1.start()                  # 开启进程p1
    p2.start()                  # 开启进程p2
    p1.join()                   # 等待p1进程结束
    p2.join()                   # 等待p2进程结束
    print('-------主进程结束------')

运行结果 在这里插入图片描述

结论

  • 各进程中的g_num独立修改,互不影响。
  • 进程间默认不共享数据,需通过队列或管道实现通信。
在这里插入图片描述在这里插入图片描述

🔎2.队列(Queue)简介

队列是一种先进先出(FIFO)的数据结构,特点如下:

  1. 新元素插入到队尾。
  2. 删除操作从队首开始。

队列结构示意图 在这里插入图片描述

🔎3.多进程队列的使用

multiprocessing.Queue提供进程间安全的数据传递机制。

Queue常用方法

方法 说明
Queue(maxsize) 初始化队列(maxsize为队列容量,默认无限制)
qsize() 返回当前队列长度
empty() 判断队列是否为空
full() 判断队列是否已满
put(item, block=True, timeout) 写入数据(阻塞/非阻塞模式)
get(block=True, timeout) 读取数据(阻塞/非阻塞模式)
put_nowait(item) 非阻塞写入(等价于put(block=False)
get_nowait() 非阻塞读取(等价于get(block=False)

示例:队列基本操作

#coding=utf-8
from multiprocessing import Queue

if __name__ == '__main__':
    q=Queue(3) # 初始化一个Queue对象,最多可接收三条put消息
    q.put("消息1")
    q.put("消息2")
    print(q.full())  # 返回False
    q.put("消息3")
    print(q.full()) # 返回True

    # 因为消息列队已满,下面的try都会抛出异常,
    # 第一个try会等待2秒后再抛出异常,第二个try会立刻抛出异常
    try:
        q.put("消息4",True,2)
    except:
        print("消息列队已满,现有消息数量:%s"%q.qsize())

    try:
        q.put_nowait("消息4")
    except:
        print("消息列队已满,现有消息数量:%s"%q.qsize())

    # 读取消息时,先判断消息列队是否为空,再读取
    if not q.empty():
        print('----从队列中获取消息---')
        for i in range(q.qsize()):
            print(q.get_nowait())
    # 先判断消息列队是否已满,再写入
    if not q.full():
        q.put_nowait("消息4")

运行结果 在这里插入图片描述

🔎4.使用队列实现进程间通信

示例:通过队列传递数据

# -*- coding: utf-8 -*-
from multiprocessing import Process, Queue
import  time

# 向队列中写入数据
def write_task(q):
    if not q.full():
        for i in range(5):
            message = "消息" + str(i)
            q.put(message)
            print("写入:%s"%message)
# 从队列读取数据
def read_task(q):
    time.sleep(1)                      # 休眠1while not q.empty():
        print("读取:%s" % q.get(True,2))     # 等待2秒,如果还没读取到任何消息,
                                           # 则抛出"Queue.Empty"异常

if __name__ == "__main__":
    print("-----父进程开始-----")
    q = Queue()  # 父进程创建Queue,并传给各个子进程
    pw = Process(target=write_task, args=(q,)) # 实例化写入队列的子进程,并且传递队列
    pr = Process(target=read_task, args=(q,))  # 实例化读取队列的子进程,并且传递队列
    pw.start()   # 启动子进程 pw,写入
    pr.start()   # 启动子进程 pr,读取
    pw.join()    # 等待 pw 结束
    pr.join()    # 等待 pr 结束
    print("-----父进程结束-----")

运行结果

在这里插入图片描述在这里插入图片描述

🔎5.关键点总结

  1. 进程独立性:进程间默认不共享内存,需通过队列或管道通信。
  2. 队列操作:
    • 写入使用put(),读取使用get()
    • 设置blocktimeout处理阻塞与非阻塞场景。
  3. 多进程协作:
    • 父进程创建队列并传递给子进程。
    • 通过join()等待子进程结束,确保数据完整性。

通过队列实现进程间通信,既能保证数据安全,又简化了多进程编程的复杂度。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。