线程中的Queue

 import time
import threading
import queue
import random def putMessage():
for i in "Hello World!!!":
q.put(i)
time.sleep(random.random())
# print("size:%s"%q.qsize()) # 查看队列长度
#
# print("full:%s"%q.full()) # 查看队列是否为满的状态
#
# print("empty:%s"%q.empty())        # 查看队列是否为空的状态 def getMessage():
while True:
if not q.empty():
print(q.get())
else:
time.sleep(random.random()) if __name__ == "__main__":
q = queue.Queue() t1 = threading.Thread(target=putMessage)
t1.setDaemon(True)
t1.start() t2 = threading.Thread(target=getMessage)
t2.setDaemon(True)
t2.start() time.sleep(10)

进程中的Queue

 from multiprocessing import Queue

 q = Queue(3)    # 初始化一个Queue对象,最多可以put三条信息,如果不写3,那么久无限制

 q.put("Message01")         # 添加信息的方法
q.put("Message02")
print(q.full()) # 查看 队列 是否满了的方法 q.put("Message03")
print(q.full()) # 因为队列已经满了,所以下面的消息会出现异常,第一个 try 会等待2秒后再抛出异常,
# 第二个 try 会立刻抛出异常
try:
q.put("Message04", True, 2)
except:
print("消息队列已满,现有消息数量:%s"%q.qsize()) try:
q.put_nowait("Message04")
except:
print("消息队列已满,现有消息数量:%s"%q.qsize()) # 推荐使用的方式,先判断队列是否已满,再写入
if not q.full():
q.put_nowait("Message04") # 读取消息的时候,先判断消息队列是否为空,再读取
if not q.empty():
for i in range(q.qsize()):
print(q.get_nowait())

队列:
  为什么要用队列?列表也很好用啊。:数据安全
  创建方法:
    模式1:FIFO -- queue.Queue()
    模式2:FILO -- queue.LifoQueue()
    模式3:priorty -- queue.PriorityQueue()
      q.put([1, 'hello'])
      q.put([2, 'world'])
      级别 1 比 2 低, 1 先出来

  方法的参数:
    put()
      调用队列对象的put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常
    get()
      调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常。

  其它方法:
    q.empty() 如果队列为空,返回True,反之False
    q.full() 如果队列满了,返回True,反之False
    q.full 与 maxsize 大小对应
    q.get([block[, timeout]]) 获取队列,timeout等待时间
    q.get_nowait() 相当q.get(False)
    非阻塞 q.put(item) 写入队列,timeout等待时间
    q.put_nowait(item) 相当q.put(item, False)
    q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号

    q.join() 实际上意味着等到队列为空,再执行别的操作
    # join多少次,就需要用几次 task_done

多进程优点:

  1. 可以利用多核实现并行运算

缺点:

  1. 开销大
  2. 通信困难

管道Pipe

multiprocessing.Pipe([duplex])
返回2个连接对象(conn1, conn2),代表管道的两端,
默认是双向通信.如果duplex=False,conn1只能用来接收消息,conn2只能用来发送消息. 主要用到的方法:
send() 发送数据
recv() 接收数据
 import multiprocessing

 from multiprocessing import Process, Pipe

 def send(pipe):
pipe.send(['spam'] + [42, 'egg'])
pipe.close() def talk(pipe):
pipe.send(dict(name = 'Bob', spam = 42))
reply = pipe.recv()
print('talker got:', reply) if __name__ == '__main__':
(con1, con2) = Pipe()
sender = Process(target = send, name = 'send', args = (con1, ))
sender.start()
print("con2 got: %s" % con2.recv())#从send收到消息
con2.close() (parentEnd, childEnd) = Pipe()
child = Process(target = talk, name = 'talk', args = (childEnd,))
child.start()
print('parent got:', parentEnd.recv())
parentEnd.send({x * 2 for x in 'spam'})
child.join()
print('parent exit')

进程间的信息共享Manage

Python中进程间共享数据,处理基本的queue,pipe外,还提供了更高层次的封装。使用multiprocessing.Manager可以简单地使用这些高级接口。

Manager支持的类型有list,dict,Namespace,  Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array。
 import multiprocessing
import time def worker(d, key, value):
d[key] = value if __name__ == '__main__':
mgr = multiprocessing.Manager() d = mgr.dict()
jobs = [multiprocessing.Process(target=worker, args=(d, i, i*2))
for i in range(10)
]
for j in jobs:
j.start()
for j in jobs:
j.join()
print('Results:' )
for key, value in enumerate(dict(d)):
print("%s=%s:%s" % (key, value, d[value])) print("================================================================") manager = multiprocessing.Manager()
Global = manager.Namespace()
Global.x = 10
Global.y = 'hello'
print(Global) print("==================================================================")
问题:

列表不可变
在学习python多进程管理manager时候,当不使用join对当前进程(主进程)进行阻塞时会报错: 这样进行一下总结:在使用manager管理/进行多进程及其数据交互时候,必须对每一个manager内的进程进行join-------待所有子进程完成后再回到主进程。

多进程之进程池

 import time
from multiprocessing import Pool def worker():
for i in range(10):
print("From worker %s"%i)
time.sleep(0.5) def foo():
for i in range(10):
print("From foo %s"%i)
time.sleep(0.5) def bar():
for i in range(10):
print("From bar %s"%i)
time.sleep(0.5) if __name__ == "__main__":
pool = Pool(4) # 创建Pool对象, 3 表示同时最多可以增加 3 条进程
pool.apply_async(worker)
pool.apply_async(worker)
pool.apply_async(worker)
pool.apply_async(foo)
pool.apply_async(foo)
pool.apply_async(foo)
pool.apply_async(bar)
pool.apply_async(bar)
pool.apply_async(bar) pool.close() # 关闭进程池,禁止添加任务
pool.join() # 等待子进程结束后,主进程才往下走
print("Is done...")

并发之协程

 import time

 def consumer():
r = ''
while True:
# 3、consumer通过yield拿到消息,处理,又通过yield把结果传回;
# yield指令具有return关键字的作用。然后函数的堆栈会自动冻结(freeze)在这一行。
# 当函数调用者的下一次利用next()或generator.send()或for-in来再次调用该函数时,
# 就会从yield代码的下一行开始,继续执行,再返回下一次迭代结果。通过这种方式,迭代器可以实现无限序列和惰性求值。
n = yield r
if not n:
return
print('[CONSUMER] ←← Consuming %s...' % n)
time.sleep(1)
r = '200 OK'
def produce(c):
# 1、首先调用c.next()启动生成器
next(c)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] →→ Producing %s...' % n)
# 2、然后,一旦生产了东西,通过c.send(n)切换到consumer执行;
cr = c.send(n)
# 4、produce拿到consumer处理的结果,继续生产下一条消息;
print('[PRODUCER] Consumer return: %s' % cr)
# 5、produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
c.close()
if __name__=='__main__':
# 6、整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
c = consumer()
produce(c)

协程封装之greenlet

 import greenlet
import time
import random """
创建方法:greenlet.greenlet(self, run=None, parent=None)
主要方法:
a.switch() 切换到 a 里面执行
"""
def foo():
for i in range(10):
print("foo:",i)
time.sleep(random.random())
gb.switch() def bar():
for i in range(10):
print("bar:", i)
time.sleep(random.random())
gf.switch() if __name__ == "__main__":
gf = greenlet.greenlet(foo)
gb = greenlet.greenlet(bar) gf.switch()

协程封装之 gevent

 import gevent
from gevent import monkey
import time
import random monkey.patch_all() # 如果遇到 IO 阻塞,那么就切换到下一个 协程的程序 def foo():
for i in range(10):
print("foo:",i)
time.sleep(random.random()) def bar():
for i in range(10):
print("bar:", i)
time.sleep(random.random()) if __name__ == "__main__":
gevent.joinall([gevent.spawn(foo),
gevent.spawn(bar)]) # 固定用法,将里面的函数放入到 协程的执行序列中

python queue, pipe, manage的更多相关文章

  1. 进程队列(Queue),Pipe(管道), Manager 进行进程之间的数据传递和传输

    进程Queue,实现进程传输的队列 1.Queue from multiprocessing import Process, Queue def f(q): q.put('1') q.put('2') ...

  2. Python学习之路--进程,线程,协程

    进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Q ...

  3. python多进程,进程池,数据共享,进程通信,分布式进程

    一.操作系统中相关进程的知识   Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前 ...

  4. python任务执行之线程,进程,与协程

    一.线程 线程为程序中执行任务的最小单元,由Threading模块提供了相关操作,线程适合于IO操作密集的情况下使用 #!/usr/bin/env python # -*- coding:utf-8 ...

  5. 11.python之线程,协程,进程,

    一,进程与线程 1.什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行 ...

  6. Python自学笔记-进程,线程(Mr serven)

    对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了 ...

  7. python 全栈开发,Day41(线程概念,线程的特点,进程和线程的关系,线程和python 理论知识,线程的创建)

    昨日内容回顾 队列 队列 : 先进先出.数据进程安全 队列实现方式: 管道 + 锁 生产者消费者模型 : 解决数据供需不平衡 管道 双向通信 数据进程不安全 EOFError: 管道是由操作系统进行引 ...

  8. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))

    昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...

  9. python 全栈开发,Day40(进程间通信(队列和管道),进程间的数据共享Manager,进程池Pool)

    昨日内容回顾 进程 multiprocess Process —— 进程 在python中创建一个进程的模块 start daemon 守护进程 join 等待子进程执行结束 锁 Lock acqui ...

随机推荐

  1. Html+css编写太阳星系

    我们都知道太阳系是以太阳为中心的,和所有受到太阳的引力约束天体的集合体.包括八大行星(由离太阳从近到远的顺序:水星.金星.地球.火星.木星.土星.天王星.海王星),而我用html和css所写的就是八大 ...

  2. 软工-五月心得体会 PB16110698

    伴随着愈发红润的骄阳,火热而紧张刺激的五月悄然而至.这一个月以来,曾经让同学们“废寝忘食”的软工课大作业终于告一段落,每周一篇的读书笔记也缓到半月一篇,着实令人长吐一口气.但这一份表面的余裕当然没有看 ...

  3. usleep - 睡眠若干微秒

    总览 (SYNOPSIS) usleep [number] 描述 (DESCRIPTION) usleep 睡眠 指定的 微秒数. 缺省值 是 1. 选项 (OPTIONS) --usage 显示 简 ...

  4. vuex之module

    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象.当应用变得非常复杂时,store 对象就有可能变得相当臃肿. 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) ...

  5. python之next和send用法详解

    如果send不携带参数,那么send(None) 和next()的作用的相同的,如: def a(): print('aaa') p = ' #print(p) print('bbb') r = a( ...

  6. 2018年阿里云NoSQL数据库大事盘点

    NoSQL一词最早出现在1998年.2009年Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论,来自Rackspace的Eric Evans再次提出了NoSQL概念, ...

  7. HDU6395-Sequence 矩阵快速幂+除法分块 矩阵快速幂模板

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门  原题目描述在最下面. Solution ...

  8. markdown开篇

    def show(): print("你好世界!") print("实习的日子还是得好好学习呀!") print("加油 各位!")

  9. 《转》python 11 表达式和语句

    转自 http://www.cnblogs.com/BeginMan/p/3164600.html 一.Python语句 if语句.else语句.elif语句.条件表达式.while语句.for语句. ...

  10. 随笔-ansible-4

    触发器: 一个任务同时调用多个触发器: 为远程主机上的用户设置环境变量: 保存前一步命令的输出结果,并保存到foo中: 添加环境变量的另一种方式: 注意:lineinfile模块只适用于修改少量环境变 ...