最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python協程實踐分享

 更新時間:2022年05月24日 17:00:46   作者:林樹楷  
這篇文章主要分享的是Python協程實踐,協程簡單來說就是一個更加輕量級的線程,并且不由操作系統(tǒng)內核管理,完全由程序所控制,下文相關介紹需要的朋友可以參考一下

協程

協程簡單來說就是一個更加輕量級的線程,并且不由操作系統(tǒng)內核管理,完全由程序所控制(在用戶態(tài)執(zhí)行)。協程在子程序內部是可中斷的,然后轉而執(zhí)行其他子程序,在適當的時候返回過來繼續(xù)執(zhí)行。

協程的優(yōu)勢?(協程擁有自己的寄存器上下文和棧,調度切換時,寄存器上下文和棧保存到其他地方,在切換回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文非???。)

yield在協程中的用法

1、協程中的yield通常出現在表達式的右邊:

x = yield data

如果yield的右邊沒有表達式,默認產出的值是None,現在右邊有表達式,所以返回的是data這個值。
2、協程可以從調用法接受數據,調用通過send(x)方式將數據提供給協程,同時send方法中包含next方法,所以程序會繼續(xù)執(zhí)行。
3、協程可以
中斷執(zhí)行
,去執(zhí)行另外的協程。

經典示例

代碼:

def hello():
    data = "mima"
    while True:
        x = yield data  
        print(x)
a = hello()
next(a)
data = a.send("hello")
print(data)

代碼詳解:
程序開始執(zhí)行,函數hello不會真的執(zhí)行,而是返回一個生成器給a。
當調用到next()方法時,hello函數才開始真正執(zhí)行,執(zhí)行print方法,繼續(xù)進入while循環(huán);
程序遇到y(tǒng)ield關鍵字,程序再次中斷,此時執(zhí)行到a.send(“hello”)時,程序會從yield關鍵字繼續(xù)向下執(zhí)行,然后又再次進入while循環(huán),再次遇到y(tǒng)ield關鍵字,程序再次中斷;

協程在運行過程中的四個狀態(tài)

  • GEN_CREATE:等待開始執(zhí)行
  • GEN_RUNNING:解釋器正在執(zhí)行
  • GEN_SUSPENDED:在yield表達式處暫停
  • GEN_CLOSED:執(zhí)行結束

生產者-消費者模式(協程)

import time
def consumer():
    r = ""
    while True:
        res = yield r
        if not res:
            print("Starting.....")
            return
        print("[CONSUMER] Consuming %s...." %res)
        time.sleep(1)
        r = "200 OK"
def produce(c):
    next(c)
    n = 0
    while n<6:
        n+=1
        print("[PRODUCER] Producing %s ...."%n)
        r = c.send(n)
        print("[CONSUMER] Consumer return: %s ...."%r)
    c.close()
c = consumer()
produce(c)     

代碼分析:

  • 調用next©啟動生成器;
  • 消費者一旦生產東西,通過c.send切換到消費者consumer執(zhí)行;
  • consumer通過yield關鍵字獲取到消息,在通過yield把結果執(zhí)行;
  • 生產者拿到消費者處理過的結果,繼續(xù)生成下一條消息;
  • 當跳出循環(huán)后,生產者不生產了,通過close關閉消費者,整個過程結束;

gevent第三方庫協程支持

原理:gevent基于協程的Python網絡庫,當一個greenlet遇到IO操作(訪問網絡)自動切換到其他的greenlet等到IO操作完成后,在適當的時候切換回來繼續(xù)執(zhí)行。換而言之就是greenlet通過幫我們自動切換協程,保證有greenlet在運行,而不是一直等待IO操作。

經典代碼

由于切換時在發(fā)生IO操作時自動完成,所以gevent需要修改Python內置庫,這里可以打上猴子補?。ㄓ脕碓谶\行時動態(tài)修改已有的代碼,而不需要原有的代碼)monkey.patch_all

#!/usr/bin/python2
# coding=utf8
from gevent import monkey
monkey.patch_all()
import gevent
import requests
def handle_html(url):
    print("Starting %s。。。。" % url)
    response = requests.get(url)
    code = response.status_code
    print("%s: %s" % (url, str(code)))
if __name__ == "__main__":
    urls = ["https://www.baidu.com", "https://www.douban.com", "https://www.qq.com"]
    jobs = [ gevent.spawn(handle_html, url) for url in urls ]
    gevent.joinall(jobs)

運行結果:

結果:3個網絡連接并發(fā)執(zhí)行,但是結束的順序不同。

asyncio內置庫協程支持

原理:asyncio的編程模型就是一個消息循環(huán),從asyncio模塊中直接獲取一個Eventloop(事件循環(huán))的應用,然后把需要執(zhí)行的協程放入EventLoop中執(zhí)行,實現異步IO。

經典代碼:

import asyncio
import threading
async def hello():
    print("hello, world: %s"%threading.currentThread())
    await asyncio.sleep(1) # 
    print('hello, man %s'%threading.currentThread())

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait([hello(), hello()]))
    loop.close()

代碼解析:

  • 首先獲取一個EventLoop
  • 然后將這個hello的協程放進EventLoop,運行EventLoop,它會運行知道future被完成
  • hello協程內部執(zhí)行await asyncio.sleep(1)模擬耗時1秒的IO操作,在此期間,主線程并未等待,而是去執(zhí)行EventLoop中的其他線程,實現并發(fā)執(zhí)行。

代碼結果:

異步爬蟲實例:

#!/usr/bin/python3
import aiohttp
import asyncio
async def fetch(url, session):
    print("starting: %s" % url)
    async with session.get(url) as response:
        print("%s : %s" % (url,response.status))
        return await response.read()
async def run():
    urls = ["https://www.baidu.com", "https://www.douban.com", "http://www.mi.com"]
    tasks = []
    async with aiohttp.ClientSession() as session:
        tasks = [asyncio.ensure_future(fetch(url, session)) for url in urls] # 創(chuàng)建任務
        response = await asyncio.gather(*tasks) # 并發(fā)執(zhí)行任務

        for body in response:
            print(len(response))
if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
    loop.close()

代碼解析:

  • 創(chuàng)建一個事件循環(huán),然后將任務放到時間循環(huán)中;
  • run()方法中主要是創(chuàng)建任務,并發(fā)執(zhí)行任務,返回讀取到的網頁內容;
  • fetch()方法通過aiohttp發(fā)出指定的請求,以及返回 可等待對象;

(結束輸出網址和list中網址的順序不同,證明協程中異步I/O操作)

關于aiohttp

asyncio實現類TCP、UDP、SSL等協議,aiohttp則是基于asyncio實現的HTTP框架,由此可以用來編寫一個微型的HTTP服務器。

代碼:

from aiohttp import web
async def index(request):
    await asyncio.sleep(0.5)
    print(request.path)
    return web.Response(body=' Hello, World')
async def hello(request):
    await asyncio.sleep(0.5)
    text = 'hello, %s'%request.match_info['name']
    print(request.path)
    return web.Response(body=text.encode('utf-8'))

async def init(loop):
    app = web.Application(loop=loop)
    app.router.add_route("GET", "/" , index)
    app.router.add_route("GET","/hello/{name}", hello)
    srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)
    print("Server started at http://127.0.0.0.1:8000....")
    return srv

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(init(loop))
    loop.run_forever()

代碼解析:

  • 創(chuàng)建一個事件循環(huán),傳入到init協程中;
  • 創(chuàng)建Application實例,然后添加路由處理指定的請求;
  • 通過loop創(chuàng)建TCP服務,最后啟動事件循環(huán);

到此這篇關于Python協程實踐分享的文章就介紹到這了,更多相關Python協程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 總結的幾個Python函數方法設計原則

    總結的幾個Python函數方法設計原則

    這篇文章主要介紹了總結的幾個Python函數方法設計原則,本文講解了每個函數只做一件事、保持簡單、保持簡短、輸入使用參數、輸出使用return語句等內容,需要的朋友可以參考下
    2015-06-06
  • Python的Urllib庫的基本使用教程

    Python的Urllib庫的基本使用教程

    這篇文章主要介紹了Python的Urllib庫的基本使用教程,是用Python編寫爬蟲的必備知識,需要的朋友可以參考下
    2015-04-04
  • 詳解Python中元組的三個不常用特性

    詳解Python中元組的三個不常用特性

    元組是Python中一種重要的內置數據類型。與列表一樣,我們經常使用元組將多個對象保存為相應的數據容器。本文為大家總結了元組的三個不常用特性,感興趣的小伙伴可以了解一下
    2022-07-07
  • 用代碼幫你了解Python基礎(2)

    用代碼幫你了解Python基礎(2)

    這篇文章主要用代碼幫你了解Python基礎,使用列表,元組和條件判斷的示例代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • python如何將數據集按比例隨機切分

    python如何將數據集按比例隨機切分

    這篇文章主要介紹了python如何將數據集按比例隨機切分問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 12個Python程序員面試必備問題與答案(小結)

    12個Python程序員面試必備問題與答案(小結)

    這篇文章主要介紹了12個Python程序員面試必備問題與答案,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06
  • Python中順序結構和循環(huán)結構示例代碼

    Python中順序結構和循環(huán)結構示例代碼

    這篇文章主要介紹了Python中的條件語句和循環(huán)語句,條件語句用于根據條件執(zhí)行不同的代碼塊,循環(huán)語句用于重復執(zhí)行一段代碼,文章還詳細說明了range函數的使用和continue與break語句的作用,需要的朋友可以參考下
    2025-02-02
  • Python機器學習之KNN近鄰算法

    Python機器學習之KNN近鄰算法

    KNN可以說是最簡單的分類算法之一,同時,它也是最常用的分類算法,文中非常詳細的介紹了該算法,對正在學習python的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • python?解決?pip?時報錯?no?suchoption:?--bulid-dir?的解決辦法(最新推薦)

    python?解決?pip?時報錯?no?suchoption:?--bulid-dir?的解決辦法(最新

    在使用PyCharm虛擬環(huán)境pip時,有時會遇到錯誤提示“no?such?option:?--build-dir”,這可能是由于pip版本不兼容或其他原因導致的,本文將詳細講解如何解決這個問題,感興趣的朋友跟隨小編一起看看吧
    2023-05-05
  • PyTorch加載數據集梯度下降優(yōu)化

    PyTorch加載數據集梯度下降優(yōu)化

    這篇文章主要介紹了PyTorch加載數據集梯度下降優(yōu)化,使用DataLoader方法,并繼承DataSet抽象類,可實現對數據集進行mini_batch梯度下降優(yōu)化,需要的小伙伴可以參考一下
    2022-03-03

最新評論

房产| 阿坝县| 乃东县| 屏边| 南江县| 庆元县| 车致| 泰来县| 太原市| 宝坻区| 琼结县| 双牌县| 涟源市| 庆元县| 东阳市| 乌海市| 秀山| 乌什县| 兴隆县| 本溪市| 洪洞县| 库伦旗| 大兴区| 普定县| 舒兰市| 资源县| 景宁| 桐城市| 正宁县| 壤塘县| 灵武市| 三台县| 平陆县| 顺昌县| 伊宁市| 邵阳县| 苏尼特右旗| 昭通市| 贺兰县| 玛纳斯县| 文成县|