python queue 学习笔记

part 1:get help 

>>> import Queue
>>> Queue.__all__
['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue']
>>> help(Queue)

NAME
    Queue - A multi-producer, multi-consumer queue.

FILE
    /usr/lib/python2.6/Queue.py

MODULE DOCS
    http://docs.python.org/library/Queue

CLASSES
    Queue
        LifoQueue
        PriorityQueue
    exceptions.Exception(exceptions.BaseException)
        Empty
        Full

# 可以看到主要有5个类,Empty, Full 是两个和异常相关的类。 Queue 是基本的序列类, LifoQueue, PriorityQueue 继承了Queue.


part 2: 

主要看一下 Queue

 class Queue
     |  Create a queue object with a given maximum size.
     |
     |  If maxsize is <= 0, the queue size is infinite.
     |
     |  Methods defined here:
     |
     |  __init__(self, maxsize=0)
     |
     |  empty(self)
     |      Return True if the queue is empty, False otherwise (not reliable!).
     |
     |  full(self)
     |      Return True if the queue is full, False otherwise (not reliable!).
     |
     |  get(self, block=True, timeout=None)
     |      Remove and return an item from the queue.
     |
     |      If optional args 'block' is true and 'timeout' is None (the default),
     |      block if necessary until an item is available. If 'timeout' is
     |      a positive number, it blocks at most 'timeout' seconds and raises
     |      the Empty exception if no item was available within that time.
     |      Otherwise ('block' is false), return an item if one is immediately
     |      available, else raise the Empty exception ('timeout' is ignored
     |      in that case).
     |
     |  get_nowait(self)
     |      Remove and return an item from the queue without blocking.
     |
     |      Only get an item if one is immediately available. Otherwise
     |      raise the Empty exception.
     |
     |  join(self)
     |      Blocks until all items in the Queue have been gotten and processed.
     |
     |      The count of unfinished tasks goes up whenever an item is added to the
     |      queue. The count goes down whenever a consumer thread calls task_done()
     |      to indicate the item was retrieved and all work on it is complete.
     |
     |      When the count of unfinished tasks drops to zero, join() unblocks.
     |
     |  put(self, item, block=True, timeout=None)
     |      Put an item into the queue.
     |
     |      If optional args 'block' is true and 'timeout' is None (the default),
     |      block if necessary until a free slot is available. If 'timeout' is
     |      a positive number, it blocks at most 'timeout' seconds and raises
     |      the Full exception if no free slot was available within that time.
     |      Otherwise ('block' is false), put an item on the queue if a free slot
     |      is immediately available, else raise the Full exception ('timeout'
     |      is ignored in that case).
     |
     |  put_nowait(self, item)
     |      Put an item into the queue without blocking.
     |
     |      Only enqueue the item if a free slot is immediately available.
     |      Otherwise raise the Full exception.
     |
     |  qsize(self)
     |      Return the approximate size of the queue (not reliable!).
     |
     |  task_done(self)
     |      Indicate that a formerly enqueued task is complete.
     |
     |      Used by Queue consumer threads.  For each get() used to fetch a task,
     |      a subsequent call to task_done() tells the queue that the processing
     |      on the task is complete.
     |
     |      If a join() is currently blocking, it will resume when all items
     |      have been processed (meaning that a task_done() call was received
     |      for every item that had been put() into the queue).
     |
     |      Raises a ValueError if called more times than there were items
     |      placed in the queue.


一个应用举例:

from Queue import Queue


jia = Queue()


jia.put("jia")
jia.put("jia2")
jia.put("jia3")


print jia.empty()
print jia.qsize()


count = 1
while not jia.empty(): #jia.qsize():
    jia.get(True,1)
    count +=1
    print 'count', count


print 'qsize', jia.qsize()

Queue.Queue()  一个队列的同步实现!!
#  实例化一个Queue
实例化一个Queue 实例。调用 __init__() 方法。 默认maxsize = 0, 如果 maxsize <= 0 (maxsize < 1), 认为是队列长度没有限制的(底层做动态扩展)
>>> myqueue = Queue()

#  查看一个Queue 是否为空
>>> myqueue.empty()
True

# 查看一个Queue 是否为满
full() 与 maxsize 对应。 queue 时候为满,主要是判断 iterm 个数时候达到 maxsize 
>>> myqueue.full()
False

# 先队列中添加一个元素
缺省参数 block = True, 意为添加元素时,queue 是阻塞的,其他线程是不能操作此队列的。
如果block=False, 有一个潜在的危险: 此时向队列中添加元素,可能别的线程也会向该queue 添加线程,此时可能产生一个full exception

>>> myqueue.put('jia')
>>> myqueue.empty()
False
>>> myqueue.full()
False

# 查看队列中的元素个数
>>> myqueue.qsize()
1

# 从队头删除并返回一个iterm
# 默认参数 block = True. 如果队列为空,block

# get()  等效于 get(True,None) , 即get() 方法一直阻塞,直到取出第一个元素为止。
# NOTE: function() 中如果某一个参数使用了缺省参数,之后的参数也要使用缺省参数;
# function() 调用时,如果对某一个缺省参数传值,必须确保该参数之前的缺省参数也得到有效赋值!除非使用key=value的形式,明确告知function() 这次的赋值是对第二个参数。否则function 会将你传入的参数按照他自己的列表顺序来解析!!

# 一个常使用的写法是: myqueue.get(True,1).  第二个参数指定最大的阻塞时间,

>>> myqueue.get()
'jia'
>>> myqueue = Queue()
>>> myqueue.put('jia')
>>> myqueue.get(timeout=1)
'jia'
>>> myqueue.get(timeout=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/Queue.py", line 176, in get
    raise Empty
Queue.Empty
>>> myqueue.put('jia')
>>> myqueue.get(True)
'jia'

# 对get() 方法的推荐使用: 使用之前 通过 q.qsize(), q.empty() 检验队列时候为空, 确认队列非空后, 使用 q.get(True,1) 或者 q.get(timeout=1) 获取元素
# 如果queue 为空, q.ge() 会一直等下去,直到有一个iterm 可以被返回。

# put_nowait()  get_nowait() 是对put() get() 的扩展。
get_nowait()  相当于 get(block=False),
put_nowait(iterm) 相当于 put(iterm, False)
 
>>> myqueue  = Queue()
>>> myqueue.put('jia')
>>> myqueue.put_nowait('luo')
>>> myqueue.get_nowait()
'jia'
>>> myqueue.get_nowait()
'luo'

# join 似乎是和Queue 队列相关的一个操作!!
task_done()  完成一项任务后, task_done() 想任务已经完成的队列发送一个信号
join()  意味着等到队列为空,再执行别的操作。 似乎有一个队列锁的问题。


# task_done 不能调用多次!
>>> myqueue.task_done()
>>> myqueue.task_done()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/Queue.py", line 64, in task_done
    raise ValueError('task_done() called too many times')
ValueError: task_done() called too many times

# think 1:  Queue.qsize() == 0  和 Queue.empty() is True 有区别吗? 

 对三种队列的分析:

1、python queue模块的FIFO队列先进先出。
2、LIFO类似于堆。即先进后出。
3、还有一种是优先级队列级别越低越先出来。

针对这三种队列分别有三个构造函数:
1、class Queue.Queue(maxsize) FIFO
2、class Queue.LifoQueue(maxsize) LIFO
3、class Queue.PriorityQueue(maxsize) 优先级队列 

优先级队列有时很有用: 同样是往队列中放置一些任务,有时候需要某类任务优先被完成

class PriorityQueue(Queue)
 |  Variant of Queue that retrieves open entries in priority order (lowest first).
 |
 |  Entries are typically tuples of the form:  (priority number, data).
 |
 |  Methods inherited from Queue:

数字越小,表示优先级越高,越早被拿出。

>>> from Queue import PriorityQueue
>>> a = PriorityQueue()
>>> a.put((1,'jia'))
>>> a.put((20,'guo20'))
>>> a.put((100,'guo100'))
>>> a.put((3,'guo'))
>>> a.put((2,'luo'))
>>>
>>>
>>>
>>> a.get()
(1, 'jia')
>>> a.get()
(2, 'luo')
>>> a.get()
(3, 'guo')
>>> a.get()
(20, 'guo20')
>>> a.get()
(100, 'guo100')





# 一个 queue , threading 的使用示例。

#coding:utf-8

import   Queue
import   threading
import   time
import   random

q = Queue.Queue( 0 )   # 当有多个线程共享一个东西的时候就可以用它了
# 严格的来说,单单是队列还是很简单的。 如果和线程结合起来,就复杂了!!

NUM_WORKERS =   3

class   MyThread(threading.Thread):

      def   __init__(self,input,worktype):
        self._jobq = input
        self._work_type = worktype
       
          # 一般来说: 如果子类要想使用父类的相关属性,必须在子类中显式的调用父类的init方法;
          # 如果只是想 判断子类的一个实例的属性是父类,可以不用显式调用父类的init 方法
        threading.Thread.__init__(self)

      def   run(self):
          while   True :
              # 如果队列不为空,执行操作
              if   self._jobq.qsize() >   0 :
                  # 从 job list 中获取一个 任务, 添加一个 work_type,
                self._process_job(self._jobq.get(),self._work_type)
              else :
                  break

      def   _process_job(self, job, worktype):
        doJob(job,worktype)

def   doJob(job, worktype):
    time.sleep(random.random() *   3 )
      print   "doing" ,job, " worktype " ,worktype

if   __name__ ==   '__main__' :
      print   "begin ...."
      # 把这些东西放到 队列中!
      for   i   in   range(NUM_WORKERS *   2 ):
        q.put(i)   #放入到任务队列中去
      print   "job q size:" ,q.qsize()
   
      # range() 必须接受一个 整型数据!
   
      for   x   in   range(NUM_WORKERS):
          # 调用线程的start() 方法
        MyThread(q,x).start()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值