0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是事件循環(huán)

科技綠洲 ? 來(lái)源:Python實(shí)用寶典 ? 作者:Python實(shí)用寶典 ? 2023-11-01 10:00 ? 次閱讀

Python的Asyncio模塊提供了管理事件、協(xié)程、任務(wù)和線程的方法,以及編寫(xiě)并發(fā)代碼的原語(yǔ)。此模塊的主要組件和概念包括:

  • 事件循環(huán) : 在Asyncio模塊中,每一個(gè)進(jìn)程都有一個(gè)事件循環(huán)。
  • 協(xié)程 : 這是子程序的泛化概念。協(xié)程可以在執(zhí)行期間暫停,這樣就可以等待外部的處理(例如IO)完成之后,從之前暫停的地方恢復(fù)執(zhí)行。
  • Futures : 定義了 Future 對(duì)象,和 concurrent.futures 模塊一樣,表示尚未完成的計(jì)算。
  • Tasks : 這是Asyncio的子類(lèi),用于封裝和管理并行模式下的協(xié)程。

本節(jié)中重點(diǎn)討論事件,事實(shí)上,異步編程的上下文中,事件無(wú)比重要。因?yàn)槭录谋举|(zhì)就是異步。

1. 什么是事件循環(huán)

在計(jì)算系統(tǒng)中,可以產(chǎn)生事件的實(shí)體叫做事件源,能處理事件的實(shí)體叫做事件處理者。

此外,還有一些第三方實(shí)體叫做事件循環(huán)。它的作用是管理所有的事件,在整個(gè)程序運(yùn)行過(guò)程中不斷循環(huán)執(zhí)行,追蹤事件發(fā)生的順序?qū)⑺鼈兎诺疥?duì)列中,當(dāng)主線程空閑的時(shí)候,調(diào)用相應(yīng)的事件處理者處理事件。

最后,我們可以通過(guò)下面的偽代碼來(lái)理解事件循環(huán):

while(1) {
  events = getEvents();
  for (e in events)
    processEvent(e);
}

所有的事件都在 ** while **循環(huán)中捕捉,然后經(jīng)過(guò)事件處理者處理。事件處理的部分是系統(tǒng)唯一活躍的部分,當(dāng)一個(gè)事件處理完成,流程繼續(xù)處理下一個(gè)事件。

2. 準(zhǔn)備工作

Asyncio提供了以下方法來(lái)管理事件循環(huán):

  1. ** loop = get_event_loop() ** : 得到當(dāng)前上下文的事件循環(huán)。
  2. ** loop.call_later(time_delay, callback, arg) ** : 延后 time_delay 秒再執(zhí)行 callback 方法。
  3. ** loop.call_soon(callback, argument) ** : 盡可能快調(diào)用 callback, call_soon() 函數(shù)結(jié)束,主線程回到事件循環(huán)之后就會(huì)馬上調(diào)用 callback 。
  4. ** loop.time() ** : 以float類(lèi)型返回當(dāng)前事件循環(huán)的內(nèi)部時(shí)間。
  5. ** asyncio.set_event_loop() ** : 為當(dāng)前上下文設(shè)置事件循環(huán)。
  6. ** asyncio.new_event_loop() ** : 根據(jù)此策略創(chuàng)建一個(gè)新的事件循環(huán)并返回。
  7. ** loop.run_forever() **: 在調(diào)用 stop() 之前將一直運(yùn)行。

3. 如何做…

下面的代碼中,我們將展示如何使用Asyncio庫(kù)提供的事件循環(huán)創(chuàng)建異步模式的應(yīng)用。

import asyncio
import datetime
import time

def function_1(end_time, loop):
    print("function_1 called")
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, function_2, end_time, loop)
    else:
        loop.stop()

def function_2(end_time, loop):
    print("function_2 called ")
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, function_3, end_time, loop)
    else:
        loop.stop()

def function_3(end_time, loop):
    print("function_3 called")
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, function_1, end_time, loop)
    else:
        loop.stop()

def function_4(end_time, loop):
    print("function_5 called")
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, function_4, end_time, loop)
    else:
        loop.stop()

loop = asyncio.get_event_loop()

end_loop = loop.time() + 9.0
loop.call_soon(function_1, end_loop, loop)
# loop.call_soon(function_4, end_loop, loop)
loop.run_forever()
loop.close()

運(yùn)行結(jié)果如下:

python3 event.py
function_1 called
function_2 called
function_3 called
function_1 called
function_2 called
function_3 called
function_1 called
function_2 called
function_3 called

在這個(gè)例子中,我們定義了三個(gè)異步的任務(wù),相繼執(zhí)行,入下圖所示的順序。

圖片

首先,我們要得到這個(gè)事件循環(huán):

loop = asyncio.get_event_loop()

然后我們通過(guò)** call_soon **方法調(diào)用了 ** function_1() ** 函數(shù)。

end_loop = loop.time() + 9.0
loop.call_soon(function_1, end_loop, loop)

讓我們來(lái)看一下 ** function_1() ** 的定義:

def function_1(end_time, loop):
    print("function_1 called")
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, function_2, end_time, loop)
    else:
        loop.stop()

這個(gè)函數(shù)通過(guò)以下參數(shù)定義了應(yīng)用的異步行為:

  1. **end_time ** : 定義了 function_1() 可以運(yùn)行的最長(zhǎng)時(shí)間,并通過(guò) call_later 方法傳入到 function_2() 中作為參數(shù)
  2. **loop ** : 之前通過(guò) get_event_loop() 方法得到的事件循環(huán)。

** function_1() ** 的任務(wù)非常簡(jiǎn)單,只是打印出函數(shù)名字。當(dāng)然,里面也可以寫(xiě)非常復(fù)雜的操作。

print("function_1 called")

任務(wù)執(zhí)行結(jié)束之后,它將會(huì)比較 ** loop.time() ** **+1s 和設(shè)定的運(yùn)行時(shí)間,如果沒(méi)有超過(guò),使用call_later **在1秒之后執(zhí)行 ** function_2() **

if (loop.time() + 1.0) < end_time:
    loop.call_later(1, function_2, end_time, loop)
else:
    loop.stop()

其中**function_2() **和 ****function_3() **** 的作用類(lèi)似。如果運(yùn)行的時(shí)間超過(guò)了設(shè)定,事件循環(huán)終止。

loop.run_forever()
loop.close()
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 模塊
    +關(guān)注

    關(guān)注

    7

    文章

    2628

    瀏覽量

    47216
  • 程序
    +關(guān)注

    關(guān)注

    115

    文章

    3747

    瀏覽量

    80669
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4697

    瀏覽量

    68086
  • python
    +關(guān)注

    關(guān)注

    54

    文章

    4759

    瀏覽量

    84294
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    066. while循環(huán):5.1 循環(huán)章節(jié)課程介紹

    循環(huán)
    充八萬(wàn)
    發(fā)布于 :2023年07月05日 15:47:47

    067. while循環(huán):5.2 了解循環(huán)

    循環(huán)
    充八萬(wàn)
    發(fā)布于 :2023年07月05日 15:48:56

    066. while循環(huán):5.1 循環(huán)章節(jié)課程介紹

    循環(huán)
    充八萬(wàn)
    發(fā)布于 :2023年07月07日 03:42:29

    074. while循環(huán):5.9 循環(huán)的注意事項(xiàng)

    循環(huán)
    充八萬(wàn)
    發(fā)布于 :2023年07月07日 06:56:17

    系統(tǒng)的消息循環(huán)

    系統(tǒng)的消息循環(huán) 一、 實(shí)驗(yàn)?zāi)康膶W(xué)習(xí)使用系統(tǒng)的消息循環(huán)。掌握如何通過(guò)系統(tǒng)的消息循環(huán)來(lái)響應(yīng)鍵盤(pán)的消息,同時(shí)學(xué)會(huì)使用圖形模式
    發(fā)表于 12-25 23:56 ?1075次閱讀
    系統(tǒng)的消息<b class='flag-5'>循環(huán)</b>

    循環(huán)碼,循環(huán)碼是什么意思

    循環(huán)碼,循環(huán)碼是什么意思 循環(huán)碼是
    發(fā)表于 03-18 14:00 ?9867次閱讀

    在LabVIEW中使用的2種循環(huán)結(jié)構(gòu)While循環(huán)和For循環(huán)的詳細(xì)資料概述

    在程序設(shè)計(jì)中,如果需要重復(fù)執(zhí)行一段代碼,就需要使用循環(huán)結(jié)構(gòu)。接下來(lái)我們將介紹在 LabVIEW 中常常使用的 2 種循環(huán)結(jié)構(gòu) While 循環(huán)和 For 循環(huán)。
    發(fā)表于 06-19 08:00 ?33次下載
    在LabVIEW中使用的2種<b class='flag-5'>循環(huán)</b>結(jié)構(gòu)While<b class='flag-5'>循環(huán)</b>和For<b class='flag-5'>循環(huán)</b>的詳細(xì)資料概述

    Python的while循環(huán)是什么

    Python中有2種循環(huán)。一種循環(huán)次數(shù)明確,另一種循環(huán)次數(shù)不明確。`for循環(huán)`的循環(huán)重復(fù)次數(shù)是`明確的`,遍歷對(duì)象里有幾個(gè)元素,
    的頭像 發(fā)表于 02-23 11:15 ?1165次閱讀

    while循環(huán)

    while 循環(huán)定義:“當(dāng)…時(shí)候,執(zhí)行某段程序”。當(dāng)給定的條件為真時(shí),執(zhí)行循環(huán)體;條件為假時(shí),結(jié)束循環(huán)。
    的頭像 發(fā)表于 02-23 14:02 ?2932次閱讀
    while<b class='flag-5'>循環(huán)</b>

    C語(yǔ)言循環(huán)的比較

    一個(gè)循環(huán)體內(nèi)又包含另一個(gè)完整的循環(huán)結(jié)構(gòu),稱為循環(huán)的嵌套。內(nèi)嵌的循環(huán)體中還可以嵌套循環(huán),這就是多層循環(huán)
    的頭像 發(fā)表于 03-09 11:16 ?714次閱讀

    WHILE ...ENDWHILE:編程設(shè)定當(dāng)型循環(huán) .EXIT:離開(kāi)循環(huán),無(wú)條件退出循環(huán).

    當(dāng)型循環(huán)。一直重復(fù)指令塊直到滿足了特定條件的循環(huán)。如果不滿足條件,則用 ENDWHILE 后的下一個(gè)指令繼續(xù)程序。在每次循環(huán)執(zhí)行之前檢查條件。如果從一開(kāi)始就不滿足條件,則不執(zhí)行指令塊。循環(huán)
    的頭像 發(fā)表于 05-12 15:57 ?2418次閱讀
    WHILE ...ENDWHILE:編程設(shè)定當(dāng)型<b class='flag-5'>循環(huán)</b> .EXIT:離開(kāi)<b class='flag-5'>循環(huán)</b>,無(wú)條件退出<b class='flag-5'>循環(huán)</b>.

    for in range循環(huán)怎么使用

    for-in range 循環(huán)是Python中的一種循環(huán)結(jié)構(gòu),用于重復(fù)執(zhí)行一段代碼,而且循環(huán)次數(shù)是已知的。 在Python中,for-in range 循環(huán)有以下幾種用法: 通過(guò)指定
    的頭像 發(fā)表于 11-21 14:49 ?1.2w次閱讀

    python怎么設(shè)置循環(huán)次數(shù)

    在Python中,可以使用循環(huán)語(yǔ)句來(lái)重復(fù)執(zhí)行一段代碼多次。要設(shè)置循環(huán)次數(shù),可以使用循環(huán)的計(jì)數(shù)器來(lái)控制循環(huán)的執(zhí)行次數(shù)。以下是幾種常用的設(shè)置循環(huán)
    的頭像 發(fā)表于 11-23 15:50 ?4489次閱讀

    循環(huán)指令loop規(guī)定循環(huán)次數(shù)

    循環(huán)指令是計(jì)算機(jī)編程中非常重要的概念,它允許程序重復(fù)執(zhí)行一段代碼塊,使得程序可以更有效地處理大量數(shù)據(jù)和重復(fù)性任務(wù)。在本文中,我們將詳盡、詳實(shí)、細(xì)致地介紹循環(huán)指令的相關(guān)概念、語(yǔ)法和應(yīng)用場(chǎng)
    的頭像 發(fā)表于 02-14 16:10 ?1223次閱讀

    什么是PLC循環(huán)移位指令 PLC循環(huán)移位的特點(diǎn)

    PLC循環(huán)移位指令包括循環(huán)左移指令和循環(huán)右移指令。在循環(huán)移位過(guò)程中,移出的位并不會(huì)丟失,而是會(huì)放回空出的位上,形成一個(gè)環(huán)形移位。
    的頭像 發(fā)表于 03-07 16:57 ?1813次閱讀
    什么是PLC<b class='flag-5'>循環(huán)</b>移位指令 PLC<b class='flag-5'>循環(huán)</b>移位的特點(diǎn)