python多进程中的队列数据共享问题
0x00 起
今天在写一个小东西的时候,需要控制并发量,但又不能直接调用python multiprocessing(问题会在文后提到)。于是尝试用Queue来实现。
最一开始的思路是这样的:
from multiprocessing import Process
from Queue import Queue q = Queue(maxsize = 10) # 通过web应用往队列中添加数据
def put(num):
q.put(num) def read():
while True:
print q.get() if __name__ == '__main__':
Process(target=read, args=())
队列的数据,是从web应用中添加过来的(上面省略了bottle的代码),开了一个进程,不断从queue中读取数据,并进行处理(省略了处理过程)。
逻辑是没错的,但是在实际测试的时候,发现一个问题。
Queue.get()函数是个默认阻塞的函数,如果队列为空,会一直等待,类似于socket.recv。在测试的时候,程序一直卡在这里,也就是说read()函数并没有读到队列中的数据。
0x10 承
为了解决验证这个问题,我修改了一下代码,打印相关的信息:
# encoding: utf-8
from multiprocessing import Process
from Queue import Queue q = Queue(maxsize = 10) # 通过web应用往队列中添加数据
def put(num):
q.put(num) def read():
print q.qsize()
# while True:
# print q.get() if __name__ == '__main__':
put(2333)
print q.qsize()
Process(target=read, args=()).start()
打印出来的结果是1 0。在新开的进程中的队列,果然是空的。
去查了一下资料(http://my.oschina.net/yangyanxing/blog/296052),给出的解释是:队列对象不能在父进程与子进程间通信
0x20 转
最后得知multiprocessing提供了Queue供调用,可完美解决这个问题。
# encoding: utf-8
from multiprocessing import Process, Queue q = Queue(10) # 通过web应用往队列中添加数据
def put(num):
q.put(num) def read():
while True:
print q.get() if __name__ == '__main__':
put(2333)
print q.qsize()
Process(target=read, args=()).start()
0x30 合
上面提到,在bottle中无法使用multiprocessing,稍微查了一下,给出的原因是线程中无法开进程。还没太理解。
python多进程中的队列数据共享问题的更多相关文章
- python collection 中的队列
认识中的队列 在以前的认知里,队列是先进先出,就是一头进,一头出,Queue.而无意间看到了deque 双向队列. 即从该队列的头或者尾部都能插入和移除元素.而起时间复杂度竟然是一样的!O(1),是不 ...
- python多进程没有锁队列范例
假设有一些任务要完成.为了完成这项任务,将使用几个过程.所以,将保持两个队列.一个包含任务,另一个包含已完成任务的日志. 然后实例化流程来完成任务.请注意,python队列类已经同步. 这意味着,我们 ...
- 在python多进程中使用manager和Barrier
注意:Barrier是PYTHON3才有的功能,在2中无法测试. #!/usr/bin/env python # -*- coding: utf-8 -*- import multiprocessin ...
- python多进程-----multiprocessing包
multiprocessing并非是python的一个模块,而是python中多进程管理的一个包,在学习的时候可以与threading这个模块作类比,正如我们在上一篇转载的文章中所提,python的多 ...
- 一篇文章搞定Python多进程(全)
1.Python多进程模块 Python中的多进程是通过multiprocessing包来实现的,和多线程的threading.Thread差不多,它可以利用multiprocessing.Proce ...
- python多进程,进程池,数据共享,进程通信,分布式进程
一.操作系统中相关进程的知识 Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前 ...
- Python 多进程编程之 进程间的通信(在Pool中Queue)
Python 多进程编程之 进程间的通信(在Pool中Queue) 1,在进程池中进程间的通信,原理与普通进程之间一样,只是引用的方法不同,python对进程池通信有专用的方法 在Manager()中 ...
- Python程序中的进程操作-开启多进程(multiprocess.process)
目录 一.multiprocess模块 二.multiprocess.process模块 三.process模块介绍 3.1 方法介绍 3.2 属性介绍 3.3 在windows中使用process模 ...
- Python程序中的进程操作--—--开启多进程
Python程序中的进程操作-----开启多进程 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创 ...
随机推荐
- ganymed-ssh2使用
通过maven库获取ganymed-ssh2-262.jar,这是一个实现了ssh2协议的工具包,可以远程连接linux机器,执行命令,有些工作全靠它了 示例代码如下: <!--首先要建立连接, ...
- [改善Java代码]推荐在复杂字符串操作中使用正则表达式
一.分析 字符串的操作,诸如追加.合并.替换.倒序.分隔等,都是在编码过程中经常用到的,而且Java也提供了append.replace.reverse.split等方法来完成这些操作,它们使用起来 ...
- mac下的常用操作
打开 应用程序(command+shift+A)-实用工具-终端 open . 直接打开Macintosh系统目录 其他口令(与linux一样)ls 显示当前目录内 ...
- Sqlite官方下载对应版本注意细节
官网下载地址: http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki 下载注意事项: 1.对应.net平台 2.对 ...
- Ionic条码扫描
http://m.blog.csdn.net/article/details?id=45843819
- JAVA鼠标屏幕绘制拖拽删除矩形
import java.awt.Cursor; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; ...
- asp.net中C#获取字符串中汉字的个数实例
符串可以包括数字,字母,汉字或者其他的字符.使用Char类型的IsDigit静态方法可以判断字符串中的字符是否为数字,使用Char类型中的 IsLetter静态方法可以判断字符串中是否为字母.我们来实 ...
- 【转】Linux杀死fork产生的子进程的僵尸进程defunct
僵尸进程 就是 已经结束,但是还没有清理出去的.用kill -9 $PID 也无法杀死. 所以程序中应该避免出现僵尸进程. 用fork之后,父进程如果没有wait /waitpid 等待子进程的话,子 ...
- c#基础学习汇总----------继承
封装,继承,多态.这是面向对象的思想,也可以说是最基本的东西.说到继承,直接的说他就是面向对象中类与类之间的一种关系.通过继承,使得子类具有父类公有的受保护访问权限的属性和方法,同时子类可以通过加入新 ...
- Ubuntu 设定壁纸自动切换的shell脚本
升级到Ubuntu14.04后,感觉bug的确比12.04少多了.顶部任务栏支持半透明效果,所以整个桌面也看上去漂亮了很多.这样的桌面也是值得瞎捣鼓一下的,想到换壁纸,但是没找到设定动态更换壁纸的选项 ...