Python線程之線程安全的隊列Queue

一、什麼是隊列?

像排隊一樣,從頭到尾排成一排,還可以有人繼續往後排隊,這就是隊列。

這裡學委想說的是Queue這個類, 它是queue這個內置模塊內的一個類。

import queue
q = queue.Queue(5) #可以傳入參數指定隊列大小
queue.Queue()# 不傳或者給0或者<0的數字則創建一個無限長度的隊列

它提供瞭很多函數,下面幾個函數,我們使用的比較多:

  • get: 獲取並移除隊頭元素,就是出隊
  • put: 往隊列末尾加入元素,也就是後來者排隊
  • qsize: 獲取隊列的長度
  • empty: 隊列空瞭,沒有人在排瞭
  • full: 隊列滿瞭。

看著比較枯燥,學委畫瞭下圖展示:

這個隊列put瞭3次,依次放入:持續學習,持續開發,我雷學委。隊列長度為3

二、隊列基操 入隊/出隊/查隊列狀態

準備瞭下面的代碼:

import queue

q = queue.Queue(5)

print("學委粉絲隊列:", q)
print("空隊,學委粉絲隊列大小:", q.qsize())
print("空隊列?", q.empty())
for i in range(5):
    q.put(i)

print("隊列滿瞭?", q.full())
print("排滿瞭,學委粉絲隊列大小:", q.qsize())

while not q.empty():
    print("粉絲 %s 出隊點贊!" % q.get())
print("最後,學委粉絲隊列大小:", q.qsize())

這段代碼創建瞭一個長的為5的隊列。

然後一個循環寫滿隊列,接著再依此出隊,粉絲出隊點贊。

下面是運行效果:

是不是很簡單。

三、Queue是一個線程安全的類

前面幾篇文章,碰到下面的代碼(反復讀寫共享變量)結果總是出乎依賴!

amount = 100
def transfer(money):
    global amount
    for i in range(100000):
        amount += money

如果我們對隊列進行反復讀寫,會不會出現問題呢?

不妨,寫個代碼驗收一下:

import queue
import threading

xuewei_fans_q = queue.Queue()


def transfer(money):
    for i in range(100000):
        xuewei_fans_q.put(money)
        xuewei_fans_q.get()


# 創建4個任務重復給學委加關註/脫粉(還是希望各位編程的明日之星跟著學習,共同進步!)
t_group = []
for i in range(10):
    t = threading.Thread(target=lambda: transfer(-1))
    t_group.append(t)
    t.start()
    t = threading.Thread(target=lambda: transfer(1))
    t_group.append(t)
    t.start()
    t = threading.Thread(target=lambda: transfer(-1))
    t_group.append(t)
    t.start()
    t = threading.Thread(target=lambda: transfer(1))
    t_group.append(t)
    t.start()

for t in t_group:
    t.join()
print("-" * 16)
print("活躍線程數:", threading.active_count())
print("活躍線程:", threading.current_thread().name)
#反復對隊列進行添加數據,移除數據,隊列最後清零瞭
print("學委粉絲隊列:", xuewei_fans_q.qsize())

不管運行多少次,隊列(希望是黑粉隊列)都為0元素。

總結:
本篇學委分享瞭一個線程安全的隊列Queue,這個非常重要!但是隊列Queue這個類是線程安全的,這個是經過驗證的

到此這篇關於Python線程之線程安全的隊列的文章就介紹到這瞭,更多相關Python線程安全隊列內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: