1. 程式人生 > >Python 多執行緒|Queue佇列|生產者消費者模式|

Python 多執行緒|Queue佇列|生產者消費者模式|

Queue佇列

  • Python中,佇列是執行緒間最常用的交換資料的形式。Queue模組是提供佇列操作的模組,雖然簡單易用,但是不小心的話,還是會出現一些意外。Queue是執行緒安全的,自帶鎖,使用的時候,不用對佇列加鎖操作。
1. 將一個值放入佇列中

q.get()呼叫佇列物件的get()方法從隊頭刪除並返回一個專案。可選引數為block,預設為True。如果佇列為空且block為True,get()就使呼叫執行緒暫停,直至有專案可用。如果佇列為空且block為False,佇列將引發Empty異常。

2. Python Queue模組有三種佇列及建構函式:
  • 1.Python Queue模組的FIFO佇列先進先出。 class Queue.Queue(maxsize)
  • 2.LIFO類似於堆,即先進後出。 class Queue.LifoQueue(maxsize)
    1. 還有一種是優先順序佇列級別越低越先出來。 class Queue.PriorityQueue(maxsize)
3. 此包中的常用方法

(q.qsize() 返回佇列的大小q.empty() 如果佇列為空,返回True,反之Falseq.full() 如果佇列滿了,返回True,反之Falseq.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() 實際上意味著等到佇列為空,再執行別的操作

4.程式碼例項

實現一個執行緒不斷生成一個隨機數到一個佇列中(考慮使用Queue這個模組)
實現一個執行緒從上面的佇列裡面不斷的取出奇數
實現另外一個執行緒從上面的佇列裡面不斷取出偶數

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import threading
import Queue
import random
import time


class Producter(threading.Thread):
    """生產者執行緒"""
    def __init__(self, t_name, queue):
        self.queue = queue
        threading.Thread.__init__(self, name=t_name)

    def run(self):
        for i in range(10):
            randomnum = random.randint(1, 99)
            self.queue.put(randomnum)
            print 'put num in Queue %s' %  randomnum
            time.sleep(1)

        print 'put queue done'


class ConsumeEven(threading.Thread):
    """奇數消費執行緒"""
    def __init__(self, t_name, queue):
        self.queue = queue
        threading.Thread.__init__(self, name=t_name)

    def run(self):
        while True:
            try:
                queue_val = self.queue.get(1, 3)
            except Exception, e:
                print e
                break;

            if queue_val % 2 == 0:
                print 'Get Even Num %s ' % queue_val
            else:
                self.queue.put(queue_val)


q = Queue.Queue()
pt = Producter('producter', q)
ce = ConsumeEven('consumeeven', q)
ce.start()
pt.start()
pt.join()
ce.join()