• Python进程间通信


    如果让进程间互相说说话呢? Python为我们提供了一个函数multiprocess.Pipe和一个类: multiprocessing.Queue

    Queue实现进程间通信

    简单的理解Queue实现进程间通信的方式,就是使用了操作系统给开辟一个队列空间,各个进程看把数据放到改队列中,当然也可以从队列中把需要的信息取走

    Queue类提供了诸多实现进程间通信的方法

    方法名功能
    put( obj[ ,block=True [ ,timeout=None ] ] ) 将 obj 放入队列,其中当 block 参数设为 True 时,一旦队列被写满,则代码就会被阻塞,直到有进程取走数据并腾出空间供 obj 使用。timeout 参数用来设置阻塞的时间,即程序最多在阻塞 timeout 秒之后,如果还是没有空闲空间,则程序会抛出 queue.Full 异常。
    put_nowait(obj) 该方法的功能等同于 put(obj, False)。
    get([block=True , [timeout=None] ]) 从队列中取数据并返回,当 block 为 True 且 timeout 为 None 时,该方法会阻塞当前进程,直到队列中有可用的数据。如果 block 设为 False,则进程会直接做取数据的操作,如果取数据失败,则抛出 queue.Empty 异常(这种情形下 timeout 参数将不起作用)。如果手动 timeout 秒数,则当前进程最多被阻塞 timeout 秒,如果到时依旧没有可用的数据取出,则会抛出 queue.Empty 异常。
    get_nowait() 该方法的功能等同于 get(False)。
    empty() 判断当前队列空间是否为空,如果为空,则该方法返回 True;反之,返回 False。

    下面程序演示了如何使用Queue管道实现两个进程之间通信

    import multiprocessing
    def processput(queue,name):
        print(multiprocessing.current_process().pid,"进程放数据:",name)
        #将 name 放入队列
        queue.put(name)
    
    def processget(queue):
        print(multiprocessing.current_process().pid, "进程取数据:", queue.get())
    
    if __name__ == '__main__':
        # 创建进程通信的Queue
        queue = multiprocessing.Queue()
        # 创建子进程
        process1 = multiprocessing.Process(target=processput, args=(queue,"http://c.biancheng.net/python/"))
        process2 = multiprocessing.Process(target=processget, args=(queue, ))
        # 启动子进程
        process1.start()
        process2.start()
    
        #该子进程必须先执行完毕
        process1.join()
        #该子进程必须先执行完毕
        process2.join()

    执行结果:

    Pipe实现进程间通信

    Pipe直译过来意思是"管"或"管道", 该种实现多进程编制的方式,和实际生活中的管道是非常相似的。通常情况下,管道有2个口,而Pipe也常用来实现2个进程之间的通信,这2个进程分别位于管道的两端,一端用来发送数据,另一端用来接受数据

    使用Pipe实现进程通信,首先需要调用multiprocessing.Pipe()函数创建一个管道,改函数的语法格式如下:

    conn1, conn2 = multiprocess.Pipe([duplex=True])

    其中,conn1和conn2分别用来接受Pipe函数返回的2个端口;diplex参数默认为True,表示改管道是双向的,即位于2个端口的进程既可以发送数据,也可以接受数据,而如果将duplex值设置为False, 则表示管道是单向的,conn1只能用来接受数据,而conn2只能用来发送数据

    conn1和conn2都属于PipeConnection对象,它们还可以调用表2所示的这些方法

    方法名功能
    send(obj) 发送一个 obj 给管道的另一端,另一端使用 recv() 方法接收。需要说明的是,该 obj 必须是可序列化的,如果该对象序列化之后超过 32MB,则很可能会引发 ValueError 异常。
    recv() 接收另一端通过 send() 方法发送过来的数据。
    close() 关闭连接。
    poll([timeout]) 返回连接中是否还有数据可以读取。
    send_bytes(buffer[, offset[, size]]) 发送字节数据。如果没有指定 offset、size 参数,则默认发送 buffer 字节串的全部数据;如果指定了 offset 和 size 参数,则只发送 buffer 字节串中从 offset 开始、长度为 size 的字节数据。通过该方法发送的数据,应该使用 recv_bytes() 或 recv_bytes_into 方法接收。
    recv_bytes([maxlength]) 接收通过 send_bytes() 方法发送的数据,maxlength 指定最多接收的字节数。该方法返回接收到的字节数据。
    recv_bytes_into(buffer[, offset]) 功能与 recv_bytes() 方法类似,只是该方法将接收到的数据放在 buffer 中。

    下面程序演示了如何使用Pipe管道实现两个进程之间通信

    import multiprocessing
    def processsend(queue,name):
        print(multiprocessing.current_process().pid,"进程放数据:",name)
        #将 name 放入队列
        queue.send(name)
    
    def processrecv(queue):
        print(multiprocessing.current_process().pid, "进程取数据:", queue.recv())
    
    if __name__ == '__main__':
        # 创建进程通信的Queue
        conn1, conn2 = multiprocessing.Pipe(True)
        # 创建子进程
        process1 = multiprocessing.Process(target=processsend, args=(conn1,"http://c.biancheng.net/python/"))
        process2 = multiprocessing.Process(target=processrecv, args=(conn2, ))
        # 启动子进程
        process1.start()
        process2.start()
    
        #该子进程必须先执行完毕
        process1.join()
        #该子进程必须先执行完毕
        process2.join()
  • 相关阅读:
    Visual Studio Code必备插件
    webpack4+:. css属性自动追加前缀 与 mini-css-extract-plugin 插件 打包冲突问题
    webpack4.x抽取css【extract-text-webpack-plugin与mini-css-extract-plugin】
    javaScript中slice, substring,substr三者区别以及用法扩展
    Spring Boot实践——Mybatis分页插件PageHelper的使用
    Nginx配置详解
    Maven的几个常用plugin
    excel拼接数据宏
    我的Linux之路——windows10用WMware安装CentOS7.5 虚拟机详细步骤
    Spring Boot实践——多线程
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/14417460.html
Copyright © 2020-2023  润新知