千家信息网

Python中进程间通信的示例分析

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章给大家分享的是有关Python中进程间通信的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。进程概述进程(Process)是计算机中已运行程序的实体。进程与程
千家信息网最后更新 2025年01月19日Python中进程间通信的示例分析

这篇文章给大家分享的是有关Python中进程间通信的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

进程概述

进程(Process)是计算机中已运行程序的实体。进程与程序不同,程序本身只是指令、数据及器组织形式的描述,进程才是程序(那些指令和数据)的真正运行实体。例如在没有打开QQ时,QQ只是程序。打开以后,操作系统为QQ开启一个进程。再打开一个QQ,则又开启一个进程。

那么在多进程中,每个进程之间是什么关系呢?其实每个进程都有自己的地址空间、内存、数据栈以及其他记录其运行状态的辅助数据。下通过一个例子验证一下进程间是否能直接共享信息。示例代码如下:

from multiprocessing import Processdef 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个子进程对g_num变量执行不同的操作,并输出操作后的结果。运行结果如下:

-------主进程开始------
g_num is 100
-------子进程1开始------
g_num is 150
-------子进程1结束------
-------子进程2开始------
g_num is 50
-------子进程2结束------
-------主进程结束------

Process finished with exit code 0

上述代码中,分别创建了2个子进程,一个子进程中令g_num变量加50,另一个子进程令g_num变量减50。但是从运行结果看,g_num变量在父进程和2个子进程中的初识值都是100,也就是说全局变量g_num在一个进程中的结果并没有传到下一个进程中,即进程之间并没有共享信息。

要如何才能实现进程间的通信呢?Python的multiprocessing模块包装了底层的机制,提供了Queue(队列)、Pipes(管道)等多种方式来交换数据。

队列简介

队列(Queue)就是模仿现实中的排队。举个栗子(非网上购票方式,曾经的买电影票的方式),例如排队买电影票,新来的人排到队伍最后,最前面的人买完票走开,后面的人跟上。由此可见队列的两个特点:

§ 新来的都排在队尾

§ 最前面的完成后离队,后面一个跟上

多进程队列的使用

进程间有时需要通信,操作系统提供了很多机制来实现进程间的通信,如可以使用multiprocessing模块的Queue队列实现多进程之间的数据传递。Queue本身是一个消息队列程序,下面介绍一下它的使用。

初始化Queue()对象时(例如:q=Queue(num)),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头)。Queue常用方法如下:

§ Queue.qsize():返回当前队列包含的消息数量

§ Queue.empty():如果队列为空,返回True,否则返回False

§ Queue.full():如果队列满了,返回True,否则返回False

§ Queue.get([block[,timeout]]):获取队列中的一条消息,然后将其从队列中移除,block默认值为True

如果block使用默认值,且没有设置timeout(单位秒),消息队列为空,此时程序将被阻塞(停在读取状态),直到从消息队列中读到消息为止,如果设置了timeou,则会等待timeout秒,若还没有读取到任何消息,则抛出"Queue.Empty"异常
如果block值为False,消息队列为空,则会立刻抛出"Queue.Empty"异常

§ Queue.get_nowait():相当Queue.get(Flase)

§ Queue.put(item,[block[,timeout]]):将item消息写入队列,block默认值为True

如果block使用默认值,且没有设置timeout(单位秒),当消息队列已经没有空间可写入时,程序将被阻塞(停在写入状态),直到从消息队列腾出空间为止,如果设置了timeout,则会等待timeout秒,若还没有空间,则抛出"Queue.Full"异常
如果block值为False,当消息队列没有空间可写入时,则会立刻抛出"Queue.Full"异常
Queue.put_nowait(item):相当Queue.put(item,False)

示例代码如下:

#coding=utf-8from multiprocessing import Queueif __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")

程序运行结果如下:

False
True
消息队列已满,现有消息数量:3
消息队列已满,现有消息数量:3
----从队列中获取消息---
消息1
消息2
消息3

备 注

此程序只能在Windows环境下运行成功,mac系统会报错。不知道什么原因?而且单独的print(q.qsize())都报错。

使用队列在进程间通信

我们知道使用multiprocessing.Process可以创建多进程,使用multiprocessing.Queue可以实现队列的操作。结合Process和Queue实现进程间的通信。示例代码如下:

from multiprocessing import Process, Queueimport  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)                      # 休眠1秒    while 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("-----父进程结束-----")

上述代码中创建2个子进程,一个子进程负责向队列中写入数据,另一个子进程负责从队列中读取数据。为保证能够正确从队列中读取数据,设置读取数据的进程等待时间为2秒。如果2秒后仍然无法读取数据,则抛出异常。运行结果如下:

-----父进程开始-----
写入:消息0
写入:消息1
写入:消息2
写入:消息3
写入:消息4
读取:消息0
读取:消息1
读取:消息2
读取:消息3
读取:消息4
-----父进程结束-----

Process finished with exit code 0

感谢各位的阅读!关于"Python中进程间通信的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

进程 消息 队列 数据 程序 个子 数量 运行 通信 变量 示例 代码 结果 空间 实例 之间 全局 方式 状态 系统 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器共享盘如何格式化 王鹤棣唱歌软件开发 网络技术知识展板 梅尔加尼 服务器 医院系统数据库维护工资多少 在外文数据库怎么找综述 网络安全支撑岗位职责 腾讯云服务器怎么在手机上管理 软测项目哪个环节涉及到数据库 高科技大学互联网 完美世界服务器开放时间 昆山数控科技有限公司 软件开发 太仓管理软件开发服务费 如何确定代理服务器有效 网络安全研究生规划 我的世界网易外国服务器 辽宁信息化软件开发价格优惠 企业中网络技术员心得体会 市北区管理系统软件开发企业 顺丰软件开发票怎么操作 网络技术 主修课 计算机网络技术有几个大类 软件开发服务协议免费 软测项目哪个环节涉及到数据库 服务器服务定时重启 as400可以装什么数据库 网络安全技术视频下载 lazarus数据库使用教程 前端软件开发价位 缩短软件开发工期的方法
0