異步

一.協程

協程,又稱微線程,纖程。英文名Coroutine。一句話說明什麼是線程:協程是一種用戶態的輕量級線程。html

線程是系統級別的,它們是由操做系統調度;協程是程序級別的,由程序員根據須要本身調度。咱們把一個線程中的一個個函數叫作子程序,那麼子程序在執行過程當中能夠中斷去執行別的子程序;別的子程序也能夠中斷回來繼續執行以前的子程序,這就是協程。也就是說同一線程下的一段代碼<1>執行着執行着就能夠中斷,而後跳去執行另外一段代碼,當再次回來執行代碼塊<1>的時候,接着從以前中斷的地方開始執行。程序員

協程擁有本身的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。所以:協程能保留上一次調用時的狀態(即全部局部狀態的一個特定組合),每次過程重入時,就至關於進入上一次調用的狀態,換種說法:進入上一次離開時所處邏輯流的位置。編程

 

1.yield實現:

yield不但能夠返回一個值,它還能夠接收調用者發出的參數session

def consumer():
    print('開始消費了')
    ret = ''
    while True:
        producter = yield ret
        if not producter:
            return
        print('消費了%s' % producter)
        ret = '200 ok'

def produce(consu):
    # 啓動生成器,第一次必須用None  <==> consumer.__next__()
    consu.send(None)
    n = 0
    while n < 5:
        n += 1
        print('生產了蘋果%d' % n)
        ret = consu.send('蘋果%d' % n)
        print('消費者返回:%s' % ret)
    consu.close()

c = consumer()
produce(c)

  

執行流程:
首先調用consu.send(None)啓動生成器;
而後,一旦生產了東西,經過consu.send(n)切換到consumer執行;
consumer經過yield拿到消息,處理,又經過yield把結果傳回;
produce拿到consumer處理的結果,繼續生產下一條消息;
produce決定不生產了,經過c.close()關閉consumer,整個過程結束。app

 

2.其他還有第三方包greenlet和gevent實現

二.asyncio

asyncio的編程模型就是一個消息循環框架

import threading
import asyncio

@asyncio.coroutine
def hello():
    print('Hello world! (%s)' % threading.currentThread())
    # 模擬耗時操做
    yield from asyncio.sleep(1)
    print('Hello again! (%s)' % threading.currentThread())

# 獲取EventLoop:
loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
# 執行coroutine
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

  

三.async/await

import asyncio

#async申明這是一個異步函數, await用於掛起自身,執行耗時操做
async def get():
    await asyncio.sleep(1)
    return 100

async def hello():
    print('開始了')
    # 模擬耗時操做
    a = await get()
    print('結束了%s' % a)

loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

  

四.aiohttp

aiohttp是基於asyncio實現的HTTP框架異步

異步簡單爬蟲示例:async

import asyncio
import aiohttp

get_contents = []

async def html(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}
    async with aiohttp.ClientSession() as session:
        async with session.get(url, headers=headers, timeout=1, verify_ssl=False) as r:
            body = await r.text()
            get_contents.append(body)


loop = asyncio.get_event_loop()
tasks = [html('http://www.baidu.com'), html('http://www.163.com')]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

print(len(get_contents))

  

輸出:
2函數

相關文章
相關標籤/搜索