1 消息队列

1.1 基本语法

消息队列:multiprocessing.Queue,Queue是对进程安全的队列,可以使用Queue实现对进程之间的数据传输;还有一个重要作用是作为缓存使用。

Queue(maxsize = 0) method of multiprocessing, returns a queue obiect

Queue(maxzize = 0)创建一个队列对象,maxsize 表示队列中最多存放消息的数量。

返回一个队列对象

1.1 队列对象操作方法:

1.1.1 put方法

put(obj [, block=True[, timeout]])

调用队列对象的put()方法将obj插入到队列中,

第一个obj为必需参数,为插入项目的值;存入消息的种类不限制。

第二个block为可选参数,默认为True,

当block为True,timeout为空时,q.put([1,2,3])、q.put([1,2,3],True) 表示将序列插入到队尾,阻塞调用,如果q队列满时,一直等待(无超时限制的阻塞调用)。

当block为True,timeout为正整数时,q.put([1,],True,2) 表示阻塞调用进程最多timeout秒,如果超过该时间仍无空间可用,则抛出Queue.Full异常(带超时的阻塞调用)。

当block为False,q.put([1,], False) 表示调用进程时如果有空闲空间则将数据放入队列中,否则立即抛出Queue.Full异常。

简而言之,timeout表示超时等待时间,当队列满时,再存入消息就会发生阻塞(True条件下有效),阻塞时间超过timeout等待时间则抛出异常。

1.1.2 get方法

get([block=True[, timeout]])

get方法可以将队列中读取并删除一个元素。

实际上,get()方法的使用与put()函数类似

第一个block可选参数,默认为True。

当block为True,timeout为空时,阻塞等待取值,直到取到为止。

当block为True,timeout为正整数时,在timeout时间内没有取到任何元素,则会抛出Queue.Empty异常;

当block为False时,如果可以取到至时,则会立刻返回该值,如果没有取到元素则会立即抛出Queue.Empty异常。

1.1.3 full()

q.full() 判断队列是否为满;若满,返回True,若不满,返回False

1.1.4 empty()

q.empty() 判断队列是否为空,若为空,则返回True

1.1.5 qsize()

q.qsize() 获取队列中消息数量

2 基础示例

示例1

from multiprocessing import Queue

#创建队列对象,队列中最大消息数量为3
q = Queue(maxsize = 3) 

#存入消息
q.put(1)
q.put('hello')#以字符串存入队列中
q.put([1,2,3,4])
q.put('hello world',True,5)

运行

Traceback (most recent call last):
  File "a.py", line 10, in <module>
    q.put('hello world',True,5)
  File "/usr/lib/python3.5/multiprocessing/queues.py", line 83, in put
    raise Full
queue.Full

因最后存入时已经超过队列的最大数量,阻塞5秒后报错

示例2

from multiprocessing import Queue

#创建队列对象,队列中最大消息数量为3
q = Queue(maxsize = 3) 

#存入消息
q.put(1)
q.put('hello')#以字符串存入队列中
q.put([1,2,3,4])

# 判断队列是否为满
print(q.full())# True
# 队列中消息数量

# 判断队列是否为空
print(q.empty()) # False
# 取出消息

print(q.get()) # hello
print(q.get()) # [1,2,3,4]
#判断队列是否为空
print(q.empty()) #True
print(q.get(True,3)) #报错queue.Empty

运行

True
3
False
1
2
hello
[1, 2, 3, 4]
True
Traceback (most recent call last):
  File "a.py", line 25, in <module>
    print(q.get(True,3)) #报错
  File "/usr/lib/python3.5/multiprocessing/queues.py", line 105, in get
    raise Empty
queue.Empty

3 综合应用

多个进程间的通信 示例1

import multiprocessing

def writer_proc(q):
    try:
        q.put(1, block = False)
    except:
        pass   

def reader_proc(q):
    try:
        print(q.get(block = False))
    except:
        pass

if __name__ == "__main__":
    q = multiprocessing.Queue()
    writer = multiprocessing.Process(target=writer_proc, args=(q,))
    writer.start()   

    reader = multiprocessing.Process(target=reader_proc, args=(q,))
    reader.start()  

    reader.join()
    writer.join()

运行结果为 1 或 在终端上没有任何显示

实际上,这时由于多线程代码各自运行所致,如果取出先运行,同时又有报错处理设置,所以不会报错;而是没有任何输出。

为了达到目的,可以在取出函数中增加sleep()函数。

import multiprocessing
import time

def writer_proc(q):
    try:
        q.put(1, block = False)
    except:
        pass   

def reader_proc(q):
    time.sleep(1)
    try:
        print(q.get(block = False))
    except:
        pass

if __name__ == "__main__":
    q = multiprocessing.Queue()
    writer = multiprocessing.Process(target=writer_proc, args=(q,))
    writer.start()   

    reader = multiprocessing.Process(target=reader_proc, args=(q,))
    reader.start()  

    reader.join()
    writer.join()

经过改良后,每一次运行代码均可达到输入输出的目的。

多个子进程间的通信示例2

多个子进程间的通信就要采用第一步中的队列Queue,比如,有以下需求,一个子进程向队列中写数据,另一个进程从队列中取数据,

# _*_ encoding:utf-8 _*_

from multiprocessing import Process,Queue,Pool,Pipe
import os,time,random

#写数据进程执行的代码:
def write(p):
    for value in ['A','B','C']:
        print ('Write---Before Put value---Put %s to queue...' % value)
        p.put(value)
        print ('Write---After Put value')
        time.sleep(random.random())
        print ('Write---After sleep')

#读数据进程执行的代码:
def read(p):
    while True:
        print ('Read---Before get value')
        value = p.get(True)
        print ('Read---After get value---Get %s from queue.' % value)

if __name__ == '__main__':
    #父进程创建Queue,并传给各个子进程:
    p = Queue()
    pw = Process(target=write,args=(p,))
    pr = Process(target=read,args=(p,))
    #启动子进程pw,写入:
    pw.start()
    #启动子进程pr,读取:
    pr.start()
    #等待pw结束:
    pw.join()
    #pr进程里是死循环,无法等待其结束,只能强行终止:
    pr.terminate()

运行

Write---Before Put value---Put A to queue...
Read---Before get value
Write---After Put value
Read---After get value---Get A from queue.
Read---Before get value
Write---After sleep
Write---Before Put value---Put B to queue...
Write---After Put value
Read---After get value---Get B from queue.
Read---Before get value
Write---After sleep
Write---Before Put value---Put C to queue...
Write---After Put value
Read---After get value---Get C from queue.
Read---Before get value
Write---After sleep

关于锁的应用,在不同程序间如果有同时对同一个队列操作的时候,为了避免错误,可以在某个函数操作队列的时候给它加把锁,这样在同一个时间内则只能有一个子进程对队列进行操作,锁也要在manager对象中的锁

示例3

from multiprocessing import  Process,Queue
import time

process_list = []
q = Queue()

def fun(name):
    time.sleep(1)
    q.put('hello' + str(name))

for i in range(10):
    p = Process(target = fun,args = (i,))
    p.start()
    process_list.append(p)

for i in process_list:
    i.join()

while not q.empty():
    print(q.get())

运行

hello0
hello1
hello3
hello2
hello4
hello6
hello5
hello9
hello8
hello7

参考:

python队列Queue

Python多进程编程

Python的multiprocessing,Queue,Process

python学习笔记——multiprocessing 多进程组件-队列Queue的更多相关文章

  1. python学习笔记——multiprocessing 多进程组件 Pipe管道

    进程间通信(IPC InterProcess Communication)是值在不同进程间传播或交换信息. IPC通过有管道(无名管道 和 有名 / 命名管道).消息队列.共享存储 / 内容.信号量. ...

  2. python学习笔记——multiprocessing 多进程组件 进程池Pool

    1 进程池Pool基本概述 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量时间,如果操作的对象数目不大时,还可以直接适用Process类动态生成 ...

  3. python学习笔记——multiprocessing 多进程模块Process

    系统自带的fork模块创建的多进程是基于Linux或Unix平台的,而window平台并不支持: python中的multiprocess为跨平台版本的多进程模块,支持子进程.通信和共享数据.执行不同 ...

  4. python学习笔记——multiprocessing 多进程中的重构方法__init__

    重构: import multiprocessing import time class ClockProcesses(multiprocessing.Process): def __init__(s ...

  5. python学习笔记六——堆栈和队列

    4.2.3 列表的查找.排序.反转 list列表可以进行添加.删除操作,此外List列表还提供了查找元素的方法.list列表的查找提供了两种方式,一种是使用index方法返回元素在列表中的位置,另一种 ...

  6. python学习笔记之四-多进程&多线程&异步非阻塞

    ProcessPoolExecutor对multiprocessing进行了高级抽象,暴露出简单的统一接口. 异步非阻塞 爬虫 对于异步IO请求的本质则是[非阻塞Socket]+[IO多路复用]: & ...

  7. Python学习笔记进阶篇——总览

    Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(Socket编程进阶&多线程.多进程) Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(异常处理) Pyth ...

  8. Python 3 并发编程多进程之队列(推荐使用)

    Python 3 并发编程多进程之队列(推荐使用) 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 可以往 ...

  9. Python学习笔记基础篇——总览

    Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...

随机推荐

  1. WampServer和phpStorm的用法

    WampServer的安装 修改默认的浏览器和文本编辑器 phpStore创建一个PHP工程 在phpStore中运行我们的项目 配制一个PHP Script运行环境 配制一个PHP Web Page ...

  2. 你应该知道的30个jQuery代码开发技巧

    1. 创建一个嵌套的过滤器 .filter(":not(:has(.selected))") //去掉所有不包含class为.selected的元素 2. 重用你的元素查询 var ...

  3. 一个常见下拉菜单的样式:一体化小三角(纯css手写解决)

    类似下拉菜单2个一体化小三角,习惯上用字体图标加jQuery处理,比较方便,但是下面纯css手写解决方式,效果也还不错,对CSS知识也是一个比较好的孔固. 小三角用了2种不同处理方式:1.利用bord ...

  4. python 分词计算文档TF-IDF值并排序

    文章来自于我的个人博客:python 分词计算文档TF-IDF值并排序 该程序实现的功能是:首先读取一些文档,然后通过jieba来分词,将分词存入文件,然后通过sklearn计算每一个分词文档中的tf ...

  5. PHP PSR基本代码规范(中文版)

    PSR-1 基本代码规范 本篇规范制定了代码基本元素的相关标准,以确保共享的PHP代码间具有较高程度的技术互通性. 关键词 “必须”("MUST").“一定不可/一定不能”(&qu ...

  6. 【转】Arp的攻防实战

    坦白讲,我是个小白,也就是各大黑客和安全厂商所说的目标群体,前者是攻击我,后者有可能保护我.但是无论如何,这次后者应该也很无能为力了——我遭遇到了传说中的Arp攻击. 在连续一周的时间里,我发现我无法 ...

  7. Druid对比Elasticsearch

    我们不是Elasticsearch的专家, 如果描绘有误, 请通过邮件列表或者其他途径告知我们. Elasticsearch 是基于Apache Lucene搜索服务器.  提供了对无模式文档的全文检 ...

  8. Oracle存储过程生成日期维度

    在数据仓库的创建过程中,往往需要创建日期维度来为以后的数据分析来服务. 方面从多个日期角度: 如:年-月-日,年-季度-月-日,年-周-日 创建表的脚本如下(存储过程的创建过程中有一步操作是向time ...

  9. GetProcAddress 使用注意事项

    使用 GetProcAddress Function 时,有以下几点需要特别留意: 1. 第二个参数类型是 LPCSTR,不是 : 2. 用 __declspec(dllexport),按 C 名称修 ...

  10. X86-64寄存器和栈帧

    简介 通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果.除此之外,它们还各自具有一些特殊功能.通用寄存器的长度取决于机器字长,汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途, ...