這篇文章帶給大家的內容是關於python中協程的詳解(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
協程,又稱微線程,纖程。英文名Coroutine
協程看起來也是子程序,但執行過程中,在子程序內部可中斷,然後轉而執行別的子程序,在適當的時候再返回來接著執行。
yield實作協程
Python對協程的支援還非常有限,用在generator中的yield可以一定程度上實現協程。雖然支援不完全,但已經可以發揮相當大的威力了。
import threading import time def producer(c): c.__next__() n=0 while n c.send(n) --> n更新 n = yield r if not n: break print('[消费者]正在调用第%s条数据' %(n)) time.sleep(1) r = 'This is ok!' if __name__=='__main__': print(threading.current_thread()) print(threading.active_count()) #查看当前进行的线程 c = consumer() producer(c) #函数中有yield, 返回值为生成器; print(threading.active_count()) #1
gevent庫實作協程
Python透過yield提供了對協程的基本支持,但是不完全。而第三方的gevent為Python提供了比較完善的協程支援。
gevent是第三方函式庫,透過greenlet實現協程,其基本思想是:由於切換是在IO操作時自動完成,所以gevent需要修改Python自帶的一些標準庫,而這個過程在啟動時透過monkey patch完成。
假設多協程執行的任務, 沒有IO操作或等待, 那麼協程間是依序運行, 而不是交替運行;
假設多協程執行的任務, IO操作或等待, 那麼協程間是交替運行;
#没有等待 import gevent from gevent import monkey monkey.patch_all() def job(n): for i in range(n): print(gevent.getcurrent(),i) def mian(): g1 = gevent.spawn(job,1) g2 = gevent.spawn(job,2) g3 = gevent.spawn(job,3) gevent.joinall([g1,g2,g3]) print('协程执行任务结束...') if __name__=="__main__": mian()
""" #有等待 import time from gevent import monkey monkey.patch_all() import gevent def job(n): for i in range(n): print(gevent.getcurrent(), i) time.sleep(1) def main1(): # 创建三个协程, 并让该协程执行job任务 g1 = gevent.spawn(job, 2) g2 = gevent.spawn(job, 3) g3 = gevent.spawn(job, 2) # 等待所有的协程执行结束, 再执行主程序; gevent.joinall([g1, g2, g3]) print("任务执行结束.....") main1()
#import time
import gevent #导入协程
from gevent import monkey
from urllib.request import urlopen #连接网络
from mytimeit import timeit #导入计算时间的装饰器
from concurrent.futures import ThreadPoolExecutor #导入线程池
def get_len_url(url):
with urlopen(url) as u_conn:
data = u_conn.read()
# print('%s该网页共%s字节' %(url,len(data)))
urls = ['http://httpbin.org', 'http://example.com/']*100
@timeit
def coroutineall():
gevents = [gevent.spawn(get_len_url,url) for url in urls]
gevent.joinall(gevents)
@timeit
def threadall():
with ThreadPoolExecutor(max_workers=100) as thpool:
thpool.map(get_len_url,urls)
if __name__=="__main__":
coroutineall()
threadall()
協程與執行緒
做一個關於協程和執行緒花費時間的對比實驗,不具參考性。
rrreee#####################以上是python中協程的詳解(附例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!