1. 程式人生 > >python基礎學習日誌day9--線程隊列queue

python基礎學習日誌day9--線程隊列queue

gin queue 多線程 是否 start wait 多少 fis line

一:線程queu作用

  Python中,queue是線程間最常用的交換數據的形式。

  隊列兩個作用:一個是解耦,一個是提高效率

二:語法

  1)隊列的類

  class queue.Queue(maxsize=0) #先入先出
  class queue.LifoQueue(maxsize=0) #last in fisrt out
  class queue.PriorityQueue(maxsize=0) #存儲數據時可設置優先級的隊列

  優先級隊列的構造函數。maxsize可以放置在隊列中的項的最大個數。

  一旦達到這個大小,插入將阻塞,直到隊列項被消耗。maxsize值為小於等於0,表示隊列的大小是無限的。

  2)隊列兩個異常

  exception queue.Empty 當調一個隊列是空的,時候調用get()或者get_nowait()會拋出阻塞

  exception queue.Full 當調一個隊列是最大值,時候調用put()或者put_nowait()會拋出非阻塞

  3)隊列的方法

  Queue.qsize() 判斷隊列大小
  Queue.empty() #空返回真
  Queue.full() # 滿反回真
  Queue.put(item, block=True, timeout=None)
  #給隊列增加一個item。如果設置了block為true,並且timeout=None,表示一直阻塞,直到隊列可以放item進去。
  如果設置了timeout=為正值,表示最多阻塞多少秒,還是不能把item放進去,就會拋出queue.Full異常。
  如果block為False,item不能放進去就拋出queue.Full。
  Queue.put_nowait(item) == Queue.put(item, block=False)
  Queue.get(block=True, timeout=None)
  #從隊列中刪除並返回一個item。如果設置了block為true,並且timeout=None,表示一直阻塞,直到隊列可以取item。  
  如果設置了timeout=為正值,表示最多阻塞多少秒,還是不能取到item,就會拋出queue.Empty
異常。
  
  如果block為False,不能取到item就拋出queue.Empty

   Queue.get_nowait() ==Queue.get(False)

  Queue.task_done()

  Queue.task_done(),每次從queue中get一個數據之後,當處理好相關問題,最後調用該方法,以提示q.join()是否停止阻塞,讓線程向前執行或者退出;

  Queue.join(),阻塞,直到queue中的數據均被刪除或者處理。為隊列中的每一項都調用一次。

  對於生產者-消費者模型,這樣做還是有問題的,因為如果queue初始為空,q.join()會直接停止阻塞,繼而執行後續語句;

  如果有多個消費者,沒有生產者,且queue始初化為一定的數據量,則可以正常執行。

三:生產者消費者模型

  在並發編程中使用生產者和消費者模式能夠解決絕大多數並發問題。該模式通過平衡生產線程和消費線程的工作能力來提高程序的整體處理數據的速度。

  為什麽要使用生產者和消費者模式

  在線程世界裏,生產者就是生產數據的線程,消費者就是消費數據的線程。在多線程開發當中,如果生產者處理速度很快,而消費者處理速度很慢,那麽生產者就必須等待消費者處理完,才能繼續生產數據。同樣的道理,如果消費者的處理能力大於生產者,那麽消費者就必須等待生產者。為了解決這個問題於是引入了生產者和消費者模式。

  什麽是生產者消費者模式

  生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,所以生產者生產完數據之後不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列裏取,阻塞隊列就相當於一個緩沖區,平衡了生產者和消費者的處理能力。

四:代碼

 

# -*- coding:utf-8 -*-
__author__ = shisanjun

import queue
import time
import threading


q=queue.Queue()

def producer(name):

    for i in range(10):
        print("%s 生產了包子%s..." %(name,i))
        q.put(i) #給隊列增加一個item
        time.sleep(1)
    q.join()#阻塞,直到queue中的數據均被刪除或者處理
    print("包子都吃完了")

def consumer(name):

    while True:
        if q.qsize()>0:
            print("%s 吃了包子%s....." %(name,q.get()))
            q.task_done() ##告知這個任務執行完了
        time.sleep(1)



p=threading.Thread(target=producer,args=("qjj",))
c=threading.Thread(target=consumer,args=("lsj",))
p.start()
c.start()

"""
qjj 生產了包子0...
lsj 吃了包子0.....
qjj 生產了包子1...
lsj 吃了包子1.....
qjj 生產了包子2...
qjj 生產了包子3...
lsj 吃了包子2.....
qjj 生產了包子4...
lsj 吃了包子3.....
lsj 吃了包子4.....
qjj 生產了包子5...
lsj 吃了包子5.....
qjj 生產了包子6...
qjj 生產了包子7...
lsj 吃了包子6.....
qjj 生產了包子8...
lsj 吃了包子7.....
lsj 吃了包子8.....
qjj 生產了包子9...
lsj 吃了包子9.....
包子都吃完了
"""

python基礎學習日誌day9--線程隊列queue