1. 程式人生 > >python筆記29-隊列Queue

python筆記29-隊列Queue

kqueue cer release 執行 post tle 基本 結果 lifo

Python的Queue模塊提供一種適用於多線程編程的FIFO實現。它可用於在生產者(producer)和消費者(consumer)之間線程安全(thread-safe)地傳遞消息或其它數據,因此多個線程可以共用同一個Queue實例。Queue的大小(元素的個數)可用來限制內存的使用。
python2和python3的導入不一樣,python2是import Queue,python3是import queue

3種Queue類型

  • FIFO:class Queue.Queue(maxsize=0)
    FIFO即First in First Out,先進先出。Queue提供了一個基本的FIFO容器,使用方法很簡單,maxsize是個整數,指明了隊列中能存放的數據個數的上限。一旦達到上限,插入會導致阻塞,直到隊列中的數據被消費掉。如果maxsize小於或者等於0,隊列大小沒有限制。

  • LIFO:class Queue.LifoQueue(maxsize=0)
    即Last in First Out,後進先出。與棧的類似,maxsize用法同上

  • 優先級隊列 :class Queue.PriorityQueue(maxsize=0)
    構造一個優先隊列。maxsize用法同上。

常用方法:

  • Queue.qsize() 返回隊列的大小
  • Queue.empty() 如果隊列為空,返回True,反之False
  • Queue.full() 如果隊列滿了,返回True,反之False
  • Queue.full 與 maxsize 大小對應
  • Queue.get([block[, timeout]])獲取隊列,timeout等待時間
  • Queue.get_nowait() 相當Queue.get(False)
  • Queue.put(item) 寫入隊列,timeout等待時間
  • Queue.put_nowait(item) 相當Queue.put(item, False)
  • Queue.task_done() 在完成一項工作之後,Queue.task_done()函數向任務已經完成的隊列發送一個信號
  • Queue.join() 實際上意味著等到隊列為空,再執行別的操作

get和put

Queue.get是從隊列裏拿數據,Queue.put是往隊列添加數據

import queue

# 設置上限maxsize=10
q = queue.Queue(maxsize=10)

# 往隊列加10個數據
for i in range(100):
    if q.qsize() >= 10:
        # 存放的數據達到上限maxsize,插入會導致阻塞
        break
    else:
        q.put(i)

# 從隊列取值
while not q.empty():
    n = q.get()
    print("本次取出數據:%s" % n)

運行結果:
本次取出數據:0
本次取出數據:1
本次取出數據:2
本次取出數據:3
本次取出數據:4
本次取出數據:5
本次取出數據:6
本次取出數據:7
本次取出數據:8
本次取出數據:9

Queue與threading

# utf-8
import queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print("Starting " + self.name)
        process_data(self.name, self.q)
        print("Exiting " + self.name)

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
        time.sleep(1)

users = ["user-1", "user-2", "user-3"]
usernames = ["name1", "name2", "name3", "name4", "name5", "name6", "name7", "name8", "name9", "name10"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1

# 創建新線程
for tName in users:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# 填充隊列
queueLock.acquire()
for word in usernames:
    workQueue.put(word)
queueLock.release()

# 等待隊列清空
while not workQueue.empty():
    pass

# 通知線程是時候退出
exitFlag = 1

# 等待所有線程完成
for t in threads:
    t.join()
print("Exiting Main Thread")

運行結果:
Starting user-1
Starting user-2
Starting user-3
user-3 processing name1
user-2 processing name2
user-1 processing name3
user-3 processing name4
user-2 processing name5
user-1 processing name6
user-3 processing name7
user-2 processing name8
user-1 processing name9
user-3 processing name10
Exiting user-2
Exiting user-1
Exiting user-3
Exiting Main Thread

python筆記29-隊列Queue