返回顶部
首页 > 资讯 > 后端开发 > Python >Python语法学习之进程间的通信方式
  • 310
分享到

Python语法学习之进程间的通信方式

2024-04-02 19:04:59 310人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录什么是进程的通信队列的创建 - multiprocessing进程之间通信的方法进程间的通信 - 队列演示案例批量给 send 函数加入数据小节进程间通信的其他方式 - 补充什么

什么是进程的通信

这里举一个例子接介绍通信的机制:通信 一词大家并不陌生,比如一个人要给他的女友打电话。当建立了通话之后,在这个通话的过程中就是建立了一条隐形的 队列 (记住这个词)。此时这个人就会通过对话的方式不停的将信息告诉女友,而这个人的女友也是在倾听着。(嗯…我个人觉得大部分情况下可能是反着来的)。

这里可以将他们两个人比作是两个进程,"这个人"的进程需要将信息发送给"女友"的进程,就需要一个队列的帮助。而女友需要不停的接收队列的信息,可以做一些其他的事情,所以两个进程之间的通信主要依赖于队列。

这个队列可以支持发送消息与接收消息,“这个人"负责发送消息,反之"女友” 负责的是接收消息。

既然队列才是重点,那么来看一下队列要如何创建。

队列的创建 - multiprocessing

依然使用 multiprocessing 模块,调用该模块的 Queue 函数来实现队列的创建。

函数名介绍参数返回值
Queue队列的创建Mac_count队列对象

Queue 函数功能介绍:调用 Queue 可以创建队列;它有一个参数 mac_count 代表队列最大可以创建多少信息,如果不传默认是无限长度。实例化一个队列对象之后,需要操作这个队列的对象进行放入与取出数据。

进程之间通信的方法

函数名介绍参数返回值
put将消息放入队列message
get获取队列消息str

put 函数功能介绍:将数据传入。它有一个参数 message ,是一个字符串类型。

get 函数功能介绍:用来接收队列中的数据。(其实这里就是一个常用的JSON场景,有很多的数据传输都是 字符串 的,队列的插入与获取就是使用的字符串,所以 json 就非常适用这个场景。)

接下来就来练习一下 队列的使用 。

进程间的通信 - 队列演示案例

代码示例如下:

# coding:utf-8


import json
import multiprocessing


class Work(object):     # 定义一个 Work 类
    def __init__(self, queue):      # 构造函数传入一个 '队列对象' --> queue
            self.queue = queue

    def send(self, message):        # 定义一个 send(发送) 函数,传入 message
                                    # [这里有个隐藏的bug,就是只判断了传入的是否字符串类型;如果传入的是函数、类、集合等依然会报错]
        if not isinstance(message, str):    # 判断传入的 message 是否为字符串,若不是,则进行 json 序列化
            message = json.dumps(message)
        self.queue.put(message)     # 利用 queue 的队列实例化对象将 message 发送出去

    def receive(self):      # 定义一个 receive(接收) 函数,不需传入参数,但是因为接收是一个源源不断的过程,所以需要使用 while 循环
        while 1:
            result = self.queue.get()   # 获取 '队列对象' --> queue 传入的message
                                        # 由于我们接收的 message 可能不是一个字符串,所以要进程异常的捕获
            try:                        # 如果传入的 message 符合 JSON 格式将赋值给 res ;若不符合,则直接使用 result 赋值 res
                res = json.loads(result)
            except:
                res = result
            print('接收到的信息为:{}'.fORMat(res))


if __name__ == '__main__':
    queue = multiprocessing.Queue()
    work = Work(queue)
    send = multiprocessing.Process(target=work.send, args=({'message': '这是一条测试的消息'},))
    receive = multiprocessing.Process(target=work.receive)

    send.start()
    receive.start()

使用队列建立进程间通信遇到的异常

但是这里会出现一个 报错,如下图:

报错截图示例如下:

这里的报错提示是 文件没有被发现的意思 。其实这里是我们使用 队列做 put() 和 get()的时候 有一把无形的加了上去,就是上图中圈中的 .SemLock 。我们不需要去关心造成这个错误的具体原因,要解决这个问题其实也很简单。

FileNotFoundError: [Errno 2] No such file or directory 异常的解决

我们只需要给 send 或者 receive 其中一个子进程添加 join 阻塞进程即可,理论上如此。但是我们的 receive子进程是一个 while循环,它会一直执行,所以只需要给 send 子进程加上一个 join 即可。

解决示意图如下:

PS:虽然解决了报错问题,但是程序没有正常退出。

实际上由于我们的 receive 进程是个 while循环,并不知道要处理到什么时候,没有办法立刻终止。所以我们需要在 receive 进程 使用 terminate() 函数终结接收端。

运行结果如下:

批量给 send 函数加入数据

新建一个函数,写入 for循环 模拟批量添加要发送的消息

然后再给这个模拟批量发送数据的函数添加一个线程

示例代码如下:

# coding:utf-8


import json
import time
import multiprocessing


class Work(object):     # 定义一个 Work 类
    def __init__(self, queue):      # 构造函数传入一个 '队列对象' --> queue
            self.queue = queue

    def send(self, message):        # 定义一个 send(发送) 函数,传入 message
                                    # [这里有个隐藏的bug,就是只判断了传入的是否字符串类型;如果传入的是函数、类、集合等依然会报错]
        if not isinstance(message, str):    # 判断传入的 message 是否为字符串,若不是,则进行 json 序列化
            message = json.dumps(message)
        self.queue.put(message)     # 利用 queue 的队列实例化对象将 message 发送出去


    def send_all(self):             # 定义一个 send_all(发送)函数,然后通过for循环模拟批量发送的 message
        for i in range(20):
            self.queue.put('第 {} 次循环,发送的消息为:{}'.format(i, i))
            time.sleep(1)



    def receive(self):      # 定义一个 receive(接收) 函数,不需传入参数,但是因为接收是一个源源不断的过程,所以需要使用 while 循环
        while 1:
            result = self.queue.get()   # 获取 '队列对象' --> queue 传入的message
                                        # 由于我们接收的 message 可能不是一个字符串,所以要进程异常的捕获
            try:                        # 如果传入的 message 符合 JSON 格式将赋值给 res ;若不符合,则直接使用 result 赋值 res
                res = json.loads(result)
            except:
                res = result
            print('接收到的信息为:{}'.format(res))


if __name__ == '__main__':
    queue = multiprocessing.Queue()
    work = Work(queue)
    send = multiprocessing.Process(target=work.send, args=({'message': '这是一条测试的消息'},))
    receive = multiprocessing.Process(target=work.receive)
    send_all = multiprocessing.Process(target=work.send_all,)


    send_all.start()    # 这里因为 send 只执行了1次,然后就结束了。而 send_all 却要循环20次,它的执行时间是最长的,信息也是发送的最多的
    send.start()
    receive.start()

    # send.join()       # 使用 send 的阻塞会造成 send_all 循环还未结束 ,receive.terminate() 函数接收端就会终结。
    send_all.join()     # 所以我们只需要阻塞最长使用率的进程就可以了
    receive.terminate()

运行结果如下:

从上图中我们可以看到 send 与 send_all 两个进程都可以通过 queue这个实例化的 Queue 对象发送消息,同样的 receive接收函数也会将两个进程传入的 message 打印输出出来。

小节

该章节我们通过队列的方式实现了进程间通信的方法,并且了解了队列的使用方法。一个队列中,有一端(这里我们演示的是 send端)通过 put方法实现添加相关的信息,另一端使用 get 方法获取相关的信息;两个进程相互配合达到一个进程通信的效果。

其实进程之间的通信不仅仅只有队列这一种方式,感兴趣的话还可以通过 管道、信号量、共享内存的方式来实现。可以自行拓展一下。

进程间通信的其他方式 - 补充

python提供了多种进程通信的方式,包括信号,管道,消息队列,信号量,共享内存,Socket

主要Queue和Pipe这两种方式,Queue用于多个进程间实现通信,Pipe是两个进程的通信。

1.管道:分为匿名管道和命名管道

匿名管道:在内核中申请一块固定大小的缓冲区,程序拥有写入和读取的权利,一般使用fock函数实现父子进程的通信

命名管道:在内存中申请一块固定大小的缓冲区,程序拥有写入和读取的权利,没有血缘关系的进程也可以进程间通信

特点:面向字节流;生命周期随内核;自带同步互斥机制;半双工,单向通信,两个管道实现双向通信

2.消息队列:在内核中创建一个队列,队列中每个元素是一个数据报,不同的进程可以通过句柄去访问这个队列。消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法。每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型。消息队列也有管道一样的不足,就是每个消息的最大长度是有上限的,每个消息队列的总的字节数是有上限的,系统上消息队列的总数也有一个上限

特点:消息队列可以被认为是一个全局的一个链表,链表节点中存放着数据报的类型和内容,有消息队列的标识符进行标记;消息队列允许一个或多个进程写入或读取消息;消息队列的生命周期随内核;消息队列可实现双向通信

3.信号量:在内核中创建一个信号量集合(本质上是数组),数组的元素(信号量)都是1,使用P操作进行-1,使用V操作+1

P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该程序的执行

V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1

PV操作用于同一个进程,实现互斥;PV操作用于不同进程,实现同步

功能:对临界资源进行保护

4.共享内存:将同一块物理内存一块映射到不同的进程的虚拟地址空间中,实现不同进程间对同一资源的共享。共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式

特点:不同从用户态到内核态的频繁切换和拷贝数据,直接从内存中读取就可以;共享内存是临界资源,所以需要操作时必须要保证原子性。使用信号量或者互斥锁都可以.

以上就是Python语法学习之进程间的通信方式的详细内容,更多关于Python进程通信方式的资料请关注编程网其它相关文章!

--结束END--

本文标题: Python语法学习之进程间的通信方式

本文链接: https://lsjlt.com/news/117191.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python语法学习之进程间的通信方式
    目录什么是进程的通信队列的创建 - multiprocessing进程之间通信的方法进程间的通信 - 队列演示案例批量给 send 函数加入数据小节进程间通信的其他方式 - 补充什么...
    99+
    2024-04-02
  • Python进程间通信方式
    目录一、通信方式二、Queue介绍三、方法介绍三、生产者和消费者模型四、什么是生产者消费者模式实现方式一:Queue实现方式二:利用JoinableQueue一、通信方式 进程彼此之...
    99+
    2024-04-02
  • Linux进程间通信的方式
    这篇文章主要介绍“Linux进程间通信的方式”,在日常操作中,相信很多人在Linux进程间通信的方式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux进程间通信的方式”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-16
  • Python进程间的通信方式是什么
    这篇文章主要介绍“Python进程间的通信方式是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python进程间的通信方式是什么”文章能帮助大家解决问题。什么是进程的通信这里举一个例子接介绍通信...
    99+
    2023-06-29
  • 进程间的通信方式(六种)
    进程之间的通信 参考文章:https://blog.csdn.net/qq_34827674/article/details/107678226 前提知识:每个进程都有自己的用户空间,而内核空间是每个进程共享的。因此进程之间想要进行通信,...
    99+
    2023-08-18
    linux 运维 服务器 进程线程
  • Python语法学习之进程池与进程锁详解
    目录进程池什么是进程池进程池的创建模块 - multiprocessing创建进程池函数 - Pool进程池的常用方法apply_async 函数演示案例close 函数与 join...
    99+
    2024-04-02
  • 一起来学习Vue的组件间通信方式
    props 父组件可以通过props向下传递数据给子组件 静态的Props 通过为子组件在父组件中的占位符添加特性的方式来达到传值的目的 动态Props 在模版中要动态的绑定父组件的...
    99+
    2024-04-02
  • Python语法学习之进程的创建与常用方法详解
    目录进程的创建模块 - multiprocessing创建进程函数 - Process进程的常用方法start 函数join 函数kill 函数 与 is_alive 函数进程的相关...
    99+
    2024-04-02
  • python进程间通信的方法有哪几种
    Python进程间通信的方法主要有以下几种: 管道(Pipe):使用multiprocessing模块中的Pipe()函数创建管...
    99+
    2024-04-09
    python
  • Python multiprocessing进程间通信方式如何实现
    这篇文章主要介绍“Python multiprocessing进程间通信方式如何实现”,在日常操作中,相信很多人在Python multiprocessing进程间通信方式如何实现问题上存在疑惑,小编查阅了各式资料,整理...
    99+
    2023-07-05
  • 详解从Node.js的child_process模块来学习父子进程之间的通信
    child_process模块提供了和popen(3)一样的方式来产生自进程,这个功能主要是通过child_process.spawn函数来提供的: const spawn = require('ch...
    99+
    2022-06-04
    父子 详解 模块
  • Python进程间通信之共享内存
    前一篇博客说了怎样通过命名管道实现进程间通信,但是要在windows是使用命名管道,需要使用python调研windows api,太麻烦,于是想到是不是可以通过共享内存的方式来实现。查了一下,Python中可以使用mmap模块来...
    99+
    2023-01-31
    进程 内存 通信
  • Linux进程间的通信方式有哪些
    本篇内容主要讲解“Linux进程间的通信方式有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux进程间的通信方式有哪些”吧!进程的概念进程是操作系统的概念,每当我们执行一个程序时,对于...
    99+
    2023-06-16
  • Android进程间通信的方式有哪些
    Android进程间通信的方式有以下几种:1. Intent:通过Intent对象进行进程间的通信。可以使用隐式Intent在不同的...
    99+
    2023-10-08
    Android
  • Linux进程间通信的方式有哪些
    本文小编为大家详细介绍“Linux进程间通信的方式有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux进程间通信的方式有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.管道管道分为有名管道和无名...
    99+
    2023-06-28
  • Linux进程间通信的方式是什么
    本篇内容主要讲解“Linux进程间通信的方式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux进程间通信的方式是什么”吧!·进程间通信:操作系统为系统提供的用于实现进程间通信的方式进...
    99+
    2023-06-29
  • Java学习之线程同步与线程间通信详解
    目录线程同步的概念同步代码块同步方法线程组线程组的相关方法线程组对象的基本应用线程间的通信线程通信简单应用线程同步的概念 由于同一个进程的多个线程共享同一块存储空间,在带来方便的同时...
    99+
    2022-12-27
    Java线程同步 Java线程通信 Java线程
  • Python进程间通信之命名管道(Win
    前面文章说了一下 Linux 命名管道的实现,今天看看 Windows 上我们怎么实现。 在 Windows 上的命名管道主要是通过调用 win32 api 的以下方法来实现的: - win32pipe.CreateNamedP...
    99+
    2023-01-31
    管道 进程 通信
  • ​​​​​​​Python入门学习之函数式编程的方法
    本篇内容介绍了“Python入门学习之函数式编程的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言在 Python 中,函数是「头等公...
    99+
    2023-06-30
  • Python的进程间通信详解
    目录进程概述队列简介多进程队列的使用使用队列在进程间通信总结进程概述 ​ 进程(Process)是计算机中已运行程序的实体。进程与程序不同,程序本身只是指令、数据及器组织形式的描述,...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作