我们知道进程之间的数据是互不影响的,但有时我们需要在进程之间通信,那怎么办呢?

认识Queue

可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息列队程序,首先用一个小实例来演示一下Queue的工作原理:

put:

  1. from multiprocessing import Queue
  2. # 创建一个实例,指定最大容量为3,若不指定则无限大(直到内存的尽头)。
  3. q = Queue(3)
  4. q.put("a")
  5. q.put("b")
  6. q.put("c")
  7. # 队列已满,此时程序将被阻塞(停在写入状态),直到从消息列队腾出空间为止。
  8. q.put("d")

get:

  1. from multiprocessing import Queue
  2. # 创建一个实例,指定最大容量为3,若不指定则无限大(直到内存的尽头)。
  3. q = Queue(3)
  4. q.put("a")
  5. q.put("b")
  6. q.put("c")
  7. q.get() # 'a'
  8. q.get() # 'b'
  9. q.get() # 'c'
  10. # # 队列为空,此时程序被阻塞,知道队列中再有数据。
  11. q.get()

说明:

  • get(self, block=True, timeout=None) 和 put(self, obj, block=True, timeout=None)
  1. get和put在默认情况是block(阻塞)为True,timeout(超时时间)=None,只要队列中没有数据或者空队列时一直被阻塞。
  2. block设为False(关闭阻塞),timeout保持默认时,只要队列中没有数据或队满就立即报异常。

    get(False)和get_nowait()是等价的,put(要入的的数据,False)和put_nowait(要入队的数据)也是等价的。
  3. block=False,timeout=2(timeout超时时间的单位是秒) 表示队满或者队空时,等待2s,如果还是队满或队空,那就报异常。表现形式为:get(False,2)、put(要入队的数据,False,2)

使用Queue

我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:

  1. from multiprocessing import Process, Queue
  2. import os
  3. import time
  4. import random
  5. # 写数据进程执行的代码
  6. def write(q):
  7. for value in ["A", "B", "C"]:
  8. print("Put %s to queue.." % value)
  9. q.put(value)
  10. time.sleep(random.random())
  11. # 读数据进程执行的代码
  12. def read(q):
  13. while True:
  14. if not q.empty():
  15. value = q.get()
  16. print("Get %s to queue.." % value)
  17. time.sleep(random.random())
  18. else:
  19. break
  20. if __name__ == '__main__':
  21. # 父进程创建Queue,传给各个子进程
  22. q = Queue()
  23. pw = Process(target=write, args=(q,))
  24. pr = Process(target=read, args=(q,))
  25. # 启动子进程
  26. pw.start()
  27. # 等待写数据的子进程结束
  28. pw.join()
  29. pr.start()
  30. pr.join()
  31. print("所有数据都写完并且读完")

进程池中的Queue

如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否则会得到一条如下的错误信息:

RuntimeError: Queue objects should only be shared between processes through inheritance.

  1. from multiprocessing import Pool, Manager
  2. import os
  3. import time
  4. import random
  5. # 写数据进程执行的代码
  6. def write(q):
  7. for value in ["A", "B", "C"]:
  8. print("Put %s to queue.." % value)
  9. q.put(value)
  10. time.sleep(random.random())
  11. # 读数据进程执行的代码
  12. def read(q):
  13. while True:
  14. if not q.empty():
  15. value = q.get()
  16. print("Get %s to queue.." % value)
  17. time.sleep(random.random())
  18. else:
  19. break
  20. if __name__ == '__main__':
  21. print("(%s) start" % os.getpid())
  22. # 父进程创建Queue,传给各个子进程
  23. q = Manager().Queue()
  24. po = Pool()
  25. po.apply(write, (q,))
  26. po.apply(read, (q,))
  27. po.close()
  28. # po.join() # 阻塞式一般不需要
  29. print("(%s) end" % os.getpid())

python进程之间的通信——Queue的更多相关文章

  1. python多进程之间的通信:消息队列Queue

    python中进程的通信:消息队列. 我们知道进程是互相独立的,各自运行在自己独立的内存空间. 所以进程之间不共享任何变量. 我们要想进程之间互相通信,传送一些东西怎么办? 需要用到消息队列!! 进程 ...

  2. Python 多进程编程之 进程间的通信(Queue)

    Python 多进程编程之 进程间的通信(Queue) 1,进程间通信Process有时是需要通信的,操作系统提供了很多机制来实现进程之间的通信,而Queue就是其中的一个方法----这是操作系统开辟 ...

  3. Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信

    Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 目录 Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 1. 僵尸进程/孤儿进 ...

  4. python全栈开发 * 进程之间的通信,进程之间数据共享 * 180726

    进程之间的通信(IPC)队列和管道一.队列 基于管道实现 管道 + 锁 数据安全(一).队列 队列遵循先进先出原则(FIFO) 多用于维护秩序,买票,秒杀 队列的所有方法: put()(给队列里添加数 ...

  5. 进程之间的通信(multiprocess.Queue)

    一.进程间通信 进程之间的数据是相互隔离的,例如 from multiprocessing import Process def task(): global n # 声明全局变量 n = 999 p ...

  6. c# IPC实现本机进程之间的通信

    IPC可以实现本地进程之间通信.这种用法不是太常见,常见的替代方案是使用wcf,remoting,web service,socket(tcp/pipe/...)等其他分布式部署方案来替代进程之间的通 ...

  7. Python 进程之间共享数据

    最近遇到多进程共享数据的问题,到网上查了有几篇博客写的蛮好的,记录下来方便以后查看. 一.Python multiprocessing 跨进程对象共享  在mp库当中,跨进程对象共享有三种方式,第一种 ...

  8. python 进程之间的通讯

    python 进程之间的通讯 #!/usr/bin/env python #-*- coding:utf-8 -*- # author:leo # datetime:2019/5/28 10:15 # ...

  9. day34——僵尸进程和孤儿进程、互斥锁、进程之间的通信

    day34 僵尸进程和孤儿进程 基于unix环境(linux,macOS) 主进程需要等待子进程结束之后,主进程才结束 主进程时刻监测子进程的运行状态,当子进程结束之后,一段时间之内,将子进程进行回收 ...

随机推荐

  1. 教程:myeclipse在线安装svn插件

    SVN 版本控制,相信开发过程中都很多有用到,今天在myeclipse 在线安装了SVN插件.下面是具体步骤,记录下,希望对有需要的朋友提供帮助. 要求: Myeclispe,电脑能连接互联网 步骤: ...

  2. 如何用Sha256进行简单的加密或者解密

    个人是今天第一次使用Sha256对数据进行加密操作,以往都是直接使用MD5加密最多也就是加盐之后再进行加密 不过可能是个人应用的只是简单的一个对数据的加密,所以感觉目前和MD5差距并不是很大. 1.首 ...

  3. fastadmin后台视频文件上传,受限制,修改php.ini配置即可

    post_max_size = 50M(根据情况)upload_max_filesize  = 50M(根据情况)

  4. under the hood

    under the hood adjective a metaphorical area that contains the underlying implementation of somethin ...

  5. Java操作符——i++ 和 ++i的区别

    问题:前置自增和后置自增的区别 Code-后置自增 public class Test { public static void main(String[] args) { int a = 2; in ...

  6. 在Linux上部署Nginx,反向代理tornado的WebSite

    1.安装 Nginx yum install -y nginx 2. 修改nginx配置文件 cd /etc/nginx/ mv nginx.conf nginx.conf.swf mv nginx. ...

  7. [Java]用于将链表变成字符串并在元素之间插入分隔符的有用函数“String.join”

    将链表变成字符串并在元素之间插入分隔符,这种动作最常见于组合sql文“select a,b,c from tb”这种场景scenario,其中a,b,c你是存贮在链表中的, 如果要加逗号要么在循环中识 ...

  8. pandas之to_datetime时区转换

    from datetime import date, datetime, timedelta     import time     import pandas as pd     from pand ...

  9. c#根据配置文件反射

    由于项目中用到了反射,准备把各个类库都先写在配置文件中,然后读取配置文件,再对配置文件中配置的类库进行反射. 这样做的好处是各个类库保持独立,其中一个类库出现问题不会影响其他类库,更新项目时,只要更新 ...

  10. vue-template-compiler作用

    vue-template-compiler的作用是什么: 看起来 template-compiler是给parse函数使用的, 那么parse函数是干什么的呢 先看一下parse的结果: 结论:使用v ...