第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Python 進階應(yīng)用教程

Python 進階應(yīng)用教程
01 Python 的對象和類 02 Python 類屬性和實例屬性 03 Python類的構(gòu)造方法、析構(gòu)方法、實例方法 04 Python 類的私有屬性和私有方法 05 Python 類的繼承和多繼承 06 Python 類實戰(zhàn) 07 Python 中的迭代器實現(xiàn)原理 08 Python 中的迭代器趣味實踐 09 Python 中的生成器實現(xiàn)原理 10 Python 中的生成器趣味實踐 11 Python 中的錯誤和異常 12 Python 中的異常處理 13 Python 中的模塊 14 Python 標準庫之 os 模塊 15 Python 標準庫之 sys 模塊 16 Python 標準庫之 math 模塊 17 Python 標準庫之 random 模塊 18 Python 標準庫之 Json 模塊 19 Python 標準庫 datetime 模塊 20 Python 中的常用第三方模塊 21 Python 中的命名空間 22 Python 中的作用域 23 Python 中的文件 IO 操作 24 Python 基礎(chǔ)實戰(zhàn) 25 Python 內(nèi)置函數(shù) 26 Python 中使用正則表達式 27 使用 Python 操作 MySQL 數(shù)據(jù)庫 28 使用 Python 操作 Mongo 數(shù)據(jù)庫 29 使用 Python 操作 Redis 數(shù)據(jù)庫 30 使用 Python 發(fā)送一封郵件 31 threading 之 Thread 的使用 32 threading 之 Lock 的基本使用 33 Python 生產(chǎn)者消費者模型 34 Python 的內(nèi)存管理與垃圾回收 35 Python 領(lǐng)域運用:網(wǎng)絡(luò)爬蟲 36 Python 領(lǐng)域運用:Web 開發(fā) 37 Python 領(lǐng)域運用:自動化運維 38 Python 領(lǐng)域運用:自動化測試

Python 生產(chǎn)者消費者模型

1. 簡介

生產(chǎn)者和消費者問題是線程模型中的經(jīng)典問題:

  • 生產(chǎn)者和消費者共享同一個存儲空間
  • 生產(chǎn)者往存儲空間中添加產(chǎn)品,消費者從存儲空間中取走產(chǎn)品
  • 當存儲空間為空時,消費者阻塞,當存儲空間滿時,生產(chǎn)者阻塞

Python 的內(nèi)置模塊 queue 提供了對生產(chǎn)者和消費者模型的支持,模塊 queue 定義了類 Queue,類 Queue 表示一個被生產(chǎn)者和消費者共享的隊列,類 Queue 提供如下常用方法:

方法 功能
get() 從隊列中取走數(shù)據(jù),如果隊列為空,則阻塞
put(item) 向隊列中放置數(shù)據(jù),如果隊列為慢,則阻塞
join() 如果隊列不為空,則等待隊列變?yōu)榭?/td>
task_done() 消費者從隊列中取走一項數(shù)據(jù),當隊列變?yōu)榭諘r,喚醒調(diào)用 join() 的線程

2. 實現(xiàn)生產(chǎn)者消費者模型

創(chuàng)建生產(chǎn)者線程和消費者線程,使用一個共享隊列連接這兩個線程,代碼如下:

import threading
import queue

q = queue.Queue()
  • 導(dǎo)入 threading 模塊和 queue 模塊
  • 創(chuàng)建共享隊列 q
def produce():
    for item in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']:
        q.put(item)
        print('produce %s' % item)
  • 創(chuàng)建生產(chǎn)者線程的入口函數(shù) produce
  • 生產(chǎn)者生產(chǎn) 8 個數(shù)據(jù)
  • 調(diào)用 q.put(item) 將生產(chǎn)的數(shù)據(jù)放入到共享隊列 q 中
def consume():
    for i in range(8):
        item = q.get()
        print('  consume %s' % item)
  • 創(chuàng)建消費者線程的入口函數(shù) consume
  • 消費者消費 8 個數(shù)據(jù)
  • 調(diào)用 q.get() 從共享隊列 q 中取走數(shù)據(jù)
producer = threading.Thread(target=produce, args=())
consumer = threading.Thread(target=consume, args=())
producer.start()
consumer.start()
producer.join()
consumer.join()
  • 創(chuàng)建生產(chǎn)者線程 producer,線程入口為 produce
  • 創(chuàng)建消費者線程 consumer,線程入口為 consume
  • 啟動生產(chǎn)者線程和消費者線程,并等待它們結(jié)束

運行程序,輸出結(jié)果如下:

produce a
produce b
  consume a
produce c
  consume b
  consume c
produce d
  consume d
produce e
  consume e
produce f
  consume f
produce g
  consume g
produce h
  consume h
  • 生產(chǎn)者生產(chǎn)了 8 個數(shù)據(jù):a、b、c、d、e、f、g、h
  • 消費者取走了 8 個數(shù)據(jù):a、b、c、d、e、f、g、h

3. 實現(xiàn)生產(chǎn)者、計算者、消費者模型

創(chuàng)建生產(chǎn)者、計算者、消費者線程:

  • 生產(chǎn)者生產(chǎn) 8 個數(shù)據(jù)
  • 計算者對生產(chǎn)者輸出的數(shù)據(jù)進行加工,將加工后的數(shù)據(jù)送往消費者
  • 消費者取走計算者輸出的數(shù)據(jù)
import threading
import queue

q0 = queue.Queue()
q1 = queue.Queue()
  • 導(dǎo)入模塊 threading 和模塊 queue
  • 使用兩個共享隊列連接這三個線程
    • 共享隊列 q0 連接生產(chǎn)者和計算者
    • 共享隊列 q1 連接計算者和消費者
def produce():
    for item in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']:
        q0.put(item)
        print('produce %s' % item)
  • 創(chuàng)建生產(chǎn)者線程的入口函數(shù) produce
  • 生產(chǎn)者生產(chǎn) 8 個數(shù)據(jù)
  • 調(diào)用 q0.put(item) 將生產(chǎn)的數(shù)據(jù)放入到共享隊列 q0 中
def compute():
    for i in range(8):
        item = q0.get()
        item = item.upper() 
        q1.put(item)
  • 創(chuàng)建計算者線程的入口函數(shù) compute
  • 調(diào)用 q0.get() 讀取生產(chǎn)者輸出數(shù)據(jù),并進行加工
  • 調(diào)用 q1.put(item) 將加工后的數(shù)據(jù)放入到共享隊列 q1 中
def consume():
    for i in range(8):
        item = q1.get()
        print('  consume %s' % item)
  • 創(chuàng)建消費者線程的入口函數(shù) consume
  • 消費者消費 8 個數(shù)據(jù)
  • 調(diào)用 q1.get() 從共享隊列 q1 中取走數(shù)據(jù)
producer = threading.Thread(target=produce, args=())
computer = threading.Thread(target=compute, args=())
consumer = threading.Thread(target=consume, args=())
producer.start()
computer.start()
consumer.start()

producer.join()
computer.join()
consumer.join()
  • 創(chuàng)建生產(chǎn)者線程 producer,線程入口為 produce
  • 創(chuàng)建計算者線程 computer,線程入口為 compute
  • 創(chuàng)建消費者線程 consumer,線程入口為 consume
  • 啟動生產(chǎn)者線程、計算者線程、消費者線程,并等待它們結(jié)束

運行程序,輸出結(jié)果如下:

produce a
produce b
produce c
  consume A
produce d
produce e
  consume B
produce f
  consume C
produce g
  consume D
produce h
  consume E
  consume F
  consume G
  consume H
  • 生產(chǎn)者生產(chǎn)了 8 個數(shù)據(jù):a、b、c、d、e、f、g、h
  • 計算者將數(shù)據(jù)加工為:A、B、C、D、E、F、G、H
  • 消費者取走了 8 個數(shù)據(jù):A、B、C、D、E、F、G、H

4. 同步生產(chǎn)者與消費者的推進速度

在生產(chǎn)者、消費者模型中,可能會存在兩者推進速度不匹配的問題:生產(chǎn)者生產(chǎn)數(shù)據(jù)的速度較快,但是,消費者取走數(shù)據(jù)的速度較慢。

可以使用 queue 的 task_done() 方法和 join() 方法同步生產(chǎn)者與消費者的推進速度:

  • 生產(chǎn)者調(diào)用 join() 方法,等待隊列中所有的數(shù)據(jù)被取走
  • 消費者調(diào)用 task_done() 方法,表示取走了隊列中的一項數(shù)據(jù),當隊列為空時,喚醒阻塞在 join() 方法中的生產(chǎn)者
import threading
import queue

q = queue.Queue()
  • 導(dǎo)入 threading 模塊和 queue 模塊
  • 創(chuàng)建共享隊列 q
def produce():
    for item in ['A', 'B', 'C', 'D']:
        q.put(item)
        print('produce %s' % item)
    q.join()
    print('------------ q is empty')

    for item in ['E', 'F', 'G', 'H']:
        q.put(item)            
        print('produce %s' % item)
    q.join()        
    print('------------ q is empty')
  • 創(chuàng)建生產(chǎn)者線程的入口函數(shù) produce
  • 首先,生產(chǎn) 4 個數(shù)據(jù):A、B、C、D
    • 調(diào)用 q.put(item) 將它們放入到隊列 q 中
    • 調(diào)用 q.join() 等待消費者將它們?nèi)咳∽?/li>
  • 然后,生產(chǎn) 4 個數(shù)據(jù):E、F、G、G
    • 調(diào)用 q.put(item) 將它們放入到隊列 q 中
    • 調(diào)用 q.join() 等待消費者將它們?nèi)咳∽?/li>
def consume():
    for i in range(8):
        item = q.get()
        print('  consume %s' % item)
        q.task_done()
  • 創(chuàng)建消費者線程的入口函數(shù) consume
  • 調(diào)用 q.get() 從隊列 q 中取走一個數(shù)據(jù)
  • 調(diào)用 q.task_done(),表示已經(jīng)從隊列 q 中取走了一個數(shù)據(jù),當隊列為空時,喚醒生產(chǎn)者
producer = threading.Thread(target=produce, args=())
consumer = threading.Thread(target=consume, args=())
producer.start()
consumer.start()
  • 創(chuàng)建生產(chǎn)者線程 producer,線程入口為 produce
  • 創(chuàng)建消費者線程 consumer,線程入口為 consume
  • 啟動生產(chǎn)者線程和消費者線程,并等待它們結(jié)束

運行程序,輸出結(jié)果如下:

produce A
produce B
  consume A
  consume B
produce C
  consume C
produce D
  consume D
------------ q is empty
produce E
  consume E
produce F
  consume F
produce G
produce H
  consume G
  consume H
------------ q is empty
  • 生產(chǎn)者生產(chǎn)第一批數(shù)據(jù) A、B、C、D,消費者將其取走
  • 當?shù)谝慌鷶?shù)據(jù)完全被消費者取走后,生產(chǎn)者才開始生產(chǎn)第二批數(shù)據(jù)
  • 生產(chǎn)者生產(chǎn)第二批數(shù)據(jù) E、F、G、H,消費者將其取走