Python語言中的協程(生產者 消費者舉例)

2021-07-31 09:47:14 字數 2334 閱讀 2389

協程又被稱為微執行緒,它的特點是不需要進行執行緒的切換,因為整個程式的執行過程中,只有乙個執行緒.沒有執行緒切換的開銷,和多執行緒相比較,執行緒數量越多,協程的效能就越高.它子程式的執行是由程式自身控制.又由於只存在乙個執行緒,所以不存在什麼變數共享等衝突問題,也不存在鎖機制,更不會出現死鎖的情況.這樣一來,執行效率就比多執行緒高的多.為了有效利用多核cpu,我們可以用程序+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的效能。

看例子:

傳統的生產者-消費者模型是乙個執行緒寫訊息,乙個執行緒取訊息,通過鎖機制控制佇列和等待,但一不小心就可能死鎖。

如果改用協程,生產者生產訊息後,直接通過yield跳轉到消費者開始執行,待消費者執行完畢後,切換回生產者繼續生產,效率極高:

# 注意 變成generator的函式,在首次呼叫的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行

defconsumer

(): r = ''

print('lalalalalaal') # 只有第一次會執行(啟動生成器), 之後再呼叫生成器就會從yield處執行

while

true:

n = yield r # 再次執行時從這裡的yield繼續執行, 將把produce傳入的引數 n 賦給區域性變數 n . 下輪迴圈再次遇到yield就會就將 r 返回給produce函式

# 所以python的yield不但可以返回乙個值,它還可以接收呼叫者發出的引數

print('***xxlalalalalaal') # 由於生成器在啟動的時候遇到上面的yield就返回了, 所以第一次不會執行這條語句. 之後每次都會被執行

ifnot n:

return

print('[consumer] consuming %s...' % n)

r = '200 ok'

# 因為yield r 所以這個r會在下一次迴圈被返回給produce函式

a = 'fake 200 ok'

# 返回的值與a無關

defproduce

(c):

c.send(none)

print('babababab')

n = 0

while n < 5:

n = n + 1

print('[producer] producing %s...' % n)

r = c.send(n) # # 獲取生成器consumer中由yield語句返回的下乙個值

print('[producer] consumer return: %s' % r)

c.close()

c = consumer() # 並不會啟動生成器, 只是將c變為乙個生成器

print('aaaaaaaaaa') # aaaaaaaaaa

produce(c)

# =>

# aaaaaaaaaa

# lalalalalaal

# babababab

# [producer] producing 1...

# ***xxlalalalalaal

# [consumer] consuming 1...

# [producer] consumer return: 200 ok

# [producer] producing 2...

# ***xxlalalalalaal

# [consumer] consuming 2...

# [producer] consumer return: 200 ok

# [producer] producing 3...

# ***xxlalalalalaal

# [consumer] consuming 3...

# [producer] consumer return: 200 ok

# [producer] producing 4...

# ***xxlalalalalaal

# [consumer] consuming 4...

# [producer] consumer return: 200 ok

# [producer] producing 5...

# ***xxlalalalalaal

# [consumer] consuming 5...

# [producer] consumer return: 200 ok

生成器generator這裡面的yield不但可以返回乙個值,它還可以接收呼叫者發出的引數.首先等待生產者發出send()呼叫的引數,執行子程式,再通過yield返回引數到生產者,生產者繼續生產,消費者子程式等待傳來引數,以此迴圈往復,直到生產者停止生產...

原 初學python 協程 無鎖生產者 消費者

引言 前幾天看了一點infoq上大神們很多的總結,服務程式設計正規化以這樣的方式進化多程序 多執行緒 非阻塞 協程。說說協程,找了一些關於greenlet的資料,協程也稱作微執行緒,是比執行緒還小的一種執行體。執行緒確實執行體就是乙個函式,在使用者空間看來,但是在核心中線程也是乙個程序,lwp所謂的...

Python之程序 執行緒 協程(生產者消費者模型)

本篇主要總結一下非常有名的生成者消費者模型 概念引用 1 為什麼要使用生產者和消費者模型?2 什麼是生產者消費者模型?生產者消費者模型是通過乙個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞佇列來進行通訊,所以生產者生產完資料之後不用等待消費者處理,直接扔給阻塞佇...

python 生產者 消費者

from bs4 import beautifulsoup import requests import time import multiprocessing as mp import re from multiprocessing import queue from multiprocessin...