日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
創(chuàng)新互聯(lián)Python教程:深究Python中的asyncio庫(kù)-shield函數(shù)

shield

我們提供的服務(wù)有:成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、延安ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的延安網(wǎng)站制作公司

asyncio.shield,用它可以屏蔽取消操作。一直到這里,我們還沒(méi)有見(jiàn)識(shí)過(guò)Task的取消。

看一個(gè)例子:

In : loop = asyncio.get_event_loop()
In : task1 = loop.create_task(a())
In : task2 = loop.create_task(b())
In : task1.cancel()
Out: True
In : await asyncio.gather(task1, task2)
Suspending a
Suspending b
---------------------------------------------------------------------------
CancelledError                            Traceback (most recent call last)
cell_name in async-def-wrapper()
CancelledError:

在上面的例子中,task1被取消了后再用asyncio.gather收集結(jié)果,直接拋CancelledError錯(cuò)誤了。這里有個(gè)細(xì)節(jié),gather支持return_exceptions參數(shù):

In : await asyncio.gather(task1, task2, return_exceptions=True)
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到,task2依然會(huì)執(zhí)行完成,但是task1的返回值是一個(gè)CancelledError錯(cuò)誤,也就是任務(wù)被取消了。如果一個(gè)創(chuàng)建后就不希望被任何情況取消,可以使用asyncio.shield保護(hù)任務(wù)能順利完成。不過(guò)要注意一個(gè)陷阱,先看錯(cuò)誤的寫(xiě)法:

In : task1 = asyncio.shield(a())
In : task2 = loop.create_task(b())
In : task1.cancel()
Out: True
In : await asyncio.gather(task1, task2, return_exceptions=True)
Suspending a
Suspending b
Resuming b
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到依然是CancelledError錯(cuò)誤,且協(xié)程a未執(zhí)行完成,正確的用法是這樣的:

In : task1 = asyncio.shield(a())
In : task2 = loop.create_task(b())
In : ts = asyncio.gather(task1, task2, return_exceptions=True)
In : task1.cancel()
Out: True
In : await ts
Suspending a
Suspending b
Resuming a
Resuming b
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到雖然結(jié)果是一個(gè)CancelledError錯(cuò)誤,但是看輸出能確認(rèn)協(xié)程實(shí)際上是執(zhí)行了的。所以正確步驟是:

先創(chuàng)建 GatheringFuture 對(duì)象 ts

取消任務(wù)

await ts

asynccontextmanager

如果你了解python,之前可能聽(tīng)過(guò)或者用過(guò)contextmanager ,一個(gè)上下文管理器。通過(guò)一個(gè)計(jì)時(shí)的例子就理解它的作用:

from contextlib import contextmanager
async def a():
    await asyncio.sleep(3)
    return 'A'
async def b():
    await asyncio.sleep(1)
    return 'B'
async def s1():
    return await asyncio.gather(a(), b())
@contextmanager
def timed(func):
    start = time.perf_counter()
    yield asyncio.run(func())
    print(f'Cost: {time.perf_counter() - start}')

timed函數(shù)用了contextmanager裝飾器,把協(xié)程的運(yùn)行結(jié)果yield出來(lái),執(zhí)行結(jié)束后還計(jì)算了耗時(shí):

In : from contextmanager import *
In : with timed(s1) as rv:
...:     print(f'Result: {rv}')
...:
Result: ['A', 'B']
Cost: 3.0052654459999992

大家先體會(huì)一下。在Python 3.7添加了asynccontextmanager,也就是異步版本的contextmanager,適合異步函數(shù)的執(zhí)行,上例可以這么改:

@asynccontextmanager
async def async_timed(func):
    start = time.perf_counter()
    yield await func()
    print(f'Cost: {time.perf_counter() - start}')
async def main():
    async with async_timed(s1) as rv:
        print(f'Result: {rv}')
In : asyncio.run(main())
Result: ['A', 'B']
Cost: 3.00414147500004

async版本的with要用async with,另外要注意yield await func()這句,相當(dāng)于yield + await func()

PS: contextmanager 和 asynccontextmanager 最好的理解方法是去看源碼注釋

下一節(jié):深究Python中的asyncio庫(kù)-函數(shù)的回調(diào)與調(diào)度


分享題目:創(chuàng)新互聯(lián)Python教程:深究Python中的asyncio庫(kù)-shield函數(shù)
標(biāo)題鏈接:http://www.5511xx.com/article/cosegij.html