前面兩章已經(jīng)介紹了yield生成器協(xié)程等方面的概念, 下面使用一個(gè)模擬一個(gè)耗時(shí)的網(wǎng)絡(luò)請(qǐng)求來講解通過asyncio實(shí)現(xiàn)并發(fā)。
模擬耗時(shí)的請(qǐng)求, 我們首先想到的是多線程, 這里就不介紹原始的多線程編程了, 使用concurrent.futures(python2需要安裝futures), 該模塊封裝了原始的多線程, 如線程池, 隊(duì)列Queue等, 返回多線程的結(jié)果并提供簡(jiǎn)單的處理api等, 所以使用這個(gè)模塊有利于我們使用多線程編程
1. 多線程

代碼說明
- 改代碼的主要功能是實(shí)現(xiàn)把1-1000列表中每個(gè)數(shù)平方, 最后求和, square_val()模擬一個(gè)耗時(shí)請(qǐng)求, 休眠0.1秒
- 使用concurrent.futures多線程模塊,使用默認(rèn)線程數(shù), 耗時(shí)0.9秒
2. 單線程協(xié)程異步io實(shí)現(xiàn)方式

代碼說明
1.使用裝飾器@asyncio.coroutine裝飾async_square_val, 將改協(xié)程函數(shù)交給asyncio處理,
- yield from asyncio.sleep(.1)這樣休眠不會(huì)阻塞時(shí)間循環(huán), 把控制權(quán)交給主循環(huán), 繼續(xù)執(zhí)行事件循環(huán)中的其它任務(wù)
- 獲取事件循環(huán)loop = asyncio.get_event_loop()
- tasks = [async_square_val(i) for i in test] 創(chuàng)建任務(wù)列表
- res, _ = loop.run_until_complete(asyncio.wait(tasks))將任務(wù)放入事件循環(huán), 最后打印時(shí)間
關(guān)于python yield大概介紹這么多, 只是說了大概, 更加細(xì)節(jié)的知識(shí)點(diǎn)需要去閱讀流暢的python這本書。另外, 從python3.5開始使用了async和await替換了asyncio協(xié)程裝飾器和yield from, 只需要替換就好了, 這里不多介紹。
補(bǔ)充: 模擬非阻塞式休眠的時(shí)候我們使用asyncio.sleep(), 當(dāng)正式使用比如http請(qǐng)求的時(shí)候我們要使用aiohttp非阻塞式的模塊請(qǐng)求http
https://github.com/aio-libs 這里提供了一些非阻塞式的第三方模塊, 如mysql, redis等等
python從yield到asyncio<第一章>
python從yield到asyncio<第二章>
再補(bǔ)充一個(gè)第四章
python從yield到asyncio<第四章>