前言
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自動化交流 QQ群:779429633