python网络编程-线程队列queue

一:线程queu作用

  Python中,queue是线程间最常用的交换数据的形式。

  队列两个作用:一个是解耦,一个是提高效率

二:语法

  1)队列的类

  class queue.Queue(maxsize=0) #先入先出
  class queue.LifoQueue(maxsize=0) #last in fisrt out 
  class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列

   优先级队列的构造函数。maxsize可以放置在队列中的项的最大个数。

  一旦达到这个大小,插入将阻塞,直到队列项被消耗。maxsize值为小于等于0,表示队列的大小是无限的。

 

  2)队列两个异常

  exception queue.Empty 当调一个队列是空的,时候调用get()或者get_nowait()会抛出阻塞

  exception queue.Full 当调一个队列是最大值,时候调用put()或者put_nowait()会抛出非阻塞

 

   3)队列的方法

  Queue.qsize() 判断队列大小
  Queue.empty() #空返回真
  Queue.full() # 满反回真
  Queue.put(item, block=True, timeout=None)
  #给队列增加一个item。如果设置了block为true,并且timeout=None,表示一直阻塞,直到队列可以放item进去。
  如果设置了timeout=为正值,表示最多阻塞多少秒,还是不能把item放进去,就会抛出queue.Full异常。
  如果block为False,item不能放进去就抛出queue.Full。
  Queue.put_nowait(item) == Queue.put(item, block=False)
  Queue.get(block=Truetimeout=None)
  #从队列中删除并返回一个item。如果设置了block为true,并且timeout=None,表示一直阻塞,直到队列可以取item。  
  如果设置了timeout=为正值,表示最多阻塞多少秒,还是不能取到item,就会抛出queue.Empty异常。  
  如果block为False,不能取到item就抛出queue.Empty 

   Queue.get_nowait() ==Queue.get(False)

   Queue.task_done()

  Queue.task_done(),每次从queue中get一个数据之后,当处理好相关问题,最后调用该方法,以提示q.join()是否停止阻塞,让线程向前执行或者退出;

  Queue.join(),阻塞,直到queue中的数据均被删除或者处理。为队列中的每一项都调用一次。

  对于生产者-消费者模型,这样做还是有问题的,因为如果queue初始为空,q.join()会直接停止阻塞,继而执行后续语句;

  如果有多个消费者,没有生产者,且queue始初化为一定的数据量,则可以正常执行。

 

 三:生产者消费者模型

  在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

  为什么要使用生产者和消费者模式

  在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

  什么是生产者消费者模式

  生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

 四:代码

 

# -*- coding:utf-8 -*-
__author__ = 'shisanjun'

import queue
import time
import threading


q=queue.Queue()

def producer(name):

    for i in range(10):
        print("%s 生产了包子%s..." %(name,i))
        q.put(i) #给队列增加一个item
        time.sleep(1)
    q.join()#阻塞,直到queue中的数据均被删除或者处理
    print("包子都吃完了")

def consumer(name):

    while True:
        if q.qsize()>0:
            print("%s 吃了包子%s....." %(name,q.get()))
            q.task_done() ##告知这个任务执行完了
        time.sleep(1)



p=threading.Thread(target=producer,args=("qjj",))
c=threading.Thread(target=consumer,args=("lsj",))
p.start()
c.start()

"""
qjj 生产了包子0...
lsj 吃了包子0.....
qjj 生产了包子1...
lsj 吃了包子1.....
qjj 生产了包子2...
qjj 生产了包子3...
lsj 吃了包子2.....
qjj 生产了包子4...
lsj 吃了包子3.....
lsj 吃了包子4.....
qjj 生产了包子5...
lsj 吃了包子5.....
qjj 生产了包子6...
qjj 生产了包子7...
lsj 吃了包子6.....
qjj 生产了包子8...
lsj 吃了包子7.....
lsj 吃了包子8.....
qjj 生产了包子9...
lsj 吃了包子9.....
包子都吃完了
"""

 

posted on 2017-06-25 14:55  shisanjun  阅读(601)  评论(0编辑  收藏  举报

导航