亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

源碼解讀Python中Event事件的使用

 更新時(shí)間:2023年12月22日 09:14:30   作者:古明地覺(jué)的編程教室  
事件(Event)主要負(fù)責(zé)多任務(wù)之間的同步,這篇文章主要來(lái)和大家詳細(xì)介紹一下它的原理以及簡(jiǎn)單使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

之前我們介紹了鎖、信號(hào)量以及隊(duì)列,那么本次來(lái)說(shuō)一說(shuō)事件(Event),它負(fù)責(zé)多任務(wù)之間的同步。

Event 對(duì)象內(nèi)部維護(hù)了一個(gè)標(biāo)志,初始時(shí)為 False,如果調(diào)用 event.set(),可以將它設(shè)置為 True, 調(diào)用 event.clear() 可以重置為 False。

然后 Event 對(duì)象還有一個(gè) wait() 方法,如果內(nèi)部的標(biāo)志為 False,那么調(diào)用該方法會(huì)阻塞。而當(dāng)標(biāo)志被設(shè)置為 True(通過(guò) set 方法)時(shí),所有任務(wù)會(huì)解除阻塞并繼續(xù)執(zhí)行。

因此 Event 對(duì)象(事件)常用于多任務(wù)之間的協(xié)調(diào)和同步,例如一個(gè)任務(wù)在等待某個(gè)事件發(fā)生,而另一個(gè)任務(wù)在發(fā)生時(shí)將標(biāo)志設(shè)置為 True,以此來(lái)通知正在等待的任務(wù)。

下面來(lái)實(shí)際看一下 Event 對(duì)象,另外 Event 有協(xié)程 Event 和線程 Event,我們分別介紹。

協(xié)程 Event

協(xié)程 Event 由 asyncio 模塊提供。

import asyncio
from asyncio import Event

async def task(event: Event):
    # 如果 event 內(nèi)部的標(biāo)志位是 False,會(huì)陷入阻塞
    print(f"陷入阻塞,因?yàn)闃?biāo)志位 = {event.is_set()}")
    await event.wait()
    print(f"解除阻塞,因?yàn)闃?biāo)志位 = {event.is_set()}")

async def main():
    event = Event()
    # 任務(wù)開(kāi)始執(zhí)行
    asyncio.create_task(task(event))
    await asyncio.sleep(3)
    # task 內(nèi)部的 event.wait() 會(huì)陷入阻塞
    # 3 秒將標(biāo)志設(shè)置為 True
    print("將 event 內(nèi)部的標(biāo)志位設(shè)置為 True")
    event.set()

asyncio.run(main())
"""
陷入阻塞,因?yàn)闃?biāo)志位 = False
將 event 內(nèi)部的標(biāo)志位設(shè)置為 True
解除阻塞,因?yàn)闃?biāo)志位 = True
"""

非常簡(jiǎn)單,當(dāng)調(diào)用 event.wait() 時(shí),如果標(biāo)志是 True,那么相當(dāng)于綠燈,直接通過(guò);如果標(biāo)志是 False,那么相當(dāng)于紅燈,需要等待。

默認(rèn)情況下是紅燈,通過(guò) event.set() 可以設(shè)置為綠燈,也可以通過(guò) event.clear() 重置為紅燈。調(diào)用 is_set() 方法可以判斷當(dāng)前是紅燈還是綠燈,True 為綠燈,F(xiàn)alse 為紅燈。

然后再來(lái)看看它的源碼實(shí)現(xiàn):

當(dāng)標(biāo)志位是 False,協(xié)程調(diào)用 wait 方法會(huì)陷入阻塞,那么阻塞要如何實(shí)現(xiàn)呢?沒(méi)錯(cuò),還是要通過(guò) Future 對(duì)象。所以 Future 對(duì)象和 asyncio 的實(shí)現(xiàn)緊密相關(guān),協(xié)程里面的阻塞等待都是基于 Future 實(shí)現(xiàn)的。

而 _waiters 負(fù)責(zé)保存協(xié)程內(nèi)部創(chuàng)建的 Future 對(duì)象,_value 則表示標(biāo)志位。至于 _loop 則用于指定事件循環(huán),這個(gè)參數(shù)已經(jīng)廢棄了。

is_set() 方法用于查看標(biāo)志位,clear() 方法用于將標(biāo)志位設(shè)置為 False,比較簡(jiǎn)單。

然后是 wait() 方法,如果調(diào)用時(shí)發(fā)現(xiàn)標(biāo)志位是 True,那么說(shuō)明是綠燈,直接通過(guò)。否則說(shuō)明是紅燈,于是創(chuàng)建一個(gè) Future 對(duì)象,并添加到 _waiters 中,然后 await 它,從而陷入阻塞。

最后是 set() 方法,如果標(biāo)志位是 False,將其設(shè)置為 True。然后將 _waiters 里面的 future 依次彈出,設(shè)置結(jié)果集,讓 await fut 的協(xié)程解除阻塞。

整個(gè)過(guò)程沒(méi)有任何難度,非常簡(jiǎn)單。

線程 Event

線程 Event 也很簡(jiǎn)單,它是由 threading 模塊提供的。

import time
import threading
from threading import Event

def task():
    # 如果 event 內(nèi)部的標(biāo)志位是 False,會(huì)陷入阻塞
    print(f"陷入阻塞,因?yàn)闃?biāo)志位 = {event.is_set()}")
    event.wait()
    print(f"解除阻塞,因?yàn)闃?biāo)志位 = {event.is_set()}")

def main():
    time.sleep(3)
    print("將 event 內(nèi)部的標(biāo)志位設(shè)置為 True")
    event.set()

event = Event()
t1 = threading.Thread(target=task)
t2 = threading.Thread(target=main)
t1.start()
t2.start()
"""
陷入阻塞,因?yàn)闃?biāo)志位 = False
將 event 內(nèi)部的標(biāo)志位設(shè)置為 True
解除阻塞,因?yàn)闃?biāo)志位 = True
"""

用法和協(xié)程 Event 幾乎沒(méi)什么區(qū)別,然后看一下它的內(nèi)部實(shí)現(xiàn)。

class Event:

    def __init__(self):
        # 條件對(duì)象,所以事件對(duì)象其實(shí)是基于條件對(duì)象的一個(gè)封裝
        self._cond = Condition(Lock())
        # 標(biāo)志位,初始為 False
        self._flag = False

    def is_set(self):
        # 標(biāo)志位是否被設(shè)置
        return self._flag

    isSet = is_set

    def set(self):
        # 修改共享變量時(shí)需要加鎖保護(hù)
        with self._cond:
            # 設(shè)置標(biāo)志位,并喚醒所有阻塞線程
            self._flag = True
            self._cond.notify_all()

    def clear(self):
        # 將標(biāo)志位設(shè)置為 False
        with self._cond:
            self._flag = False

    def wait(self, timeout=None):
        # 阻塞等待,但支持超時(shí)時(shí)間
        with self._cond:
            signaled = self._flag
            if not signaled:
                signaled = self._cond.wait(timeout)
            return signaled

非常簡(jiǎn)單,Event 內(nèi)部是基于 Condition 實(shí)現(xiàn)的,關(guān)于條件變量,我們后續(xù)再詳細(xì)介紹。

小結(jié)

以上我們就聊了聊 Event 的實(shí)現(xiàn)原理,因?yàn)椴僮飨到y(tǒng)感知不到協(xié)程,所以協(xié)程 Event 基于 Future 對(duì)象實(shí)現(xiàn)。而線程 Event 則基于條件變量,關(guān)于條件變量,我們以后再詳細(xì)展開(kāi)。

到此這篇關(guān)于源碼解讀Python中Event事件的使用的文章就介紹到這了,更多相關(guān)Python Event內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Pandas DataFrame中實(shí)現(xiàn)取單個(gè)值的讀取和修改

    Pandas DataFrame中實(shí)現(xiàn)取單個(gè)值的讀取和修改

    這篇文章主要介紹了Pandas DataFrame中實(shí)現(xiàn)取單個(gè)值的讀取和修改,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 使用python實(shí)現(xiàn)三維圖可視化

    使用python實(shí)現(xiàn)三維圖可視化

    這篇文章主要介紹了使用python實(shí)現(xiàn)三維圖可視化,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • python ansible服務(wù)及劇本編寫(xiě)

    python ansible服務(wù)及劇本編寫(xiě)

    python語(yǔ)言是運(yùn)維人員必會(huì)的語(yǔ)言,而ansible是一個(gè)基于Python開(kāi)發(fā)的自動(dòng)化運(yùn)維工具 (saltstack)。其功能實(shí)現(xiàn)基于SSH遠(yuǎn)程連接服務(wù);ansible可以實(shí)現(xiàn)批量系統(tǒng)配置、批量軟件部署、批量文件拷貝、批量運(yùn)行命令等功能
    2017-12-12
  • python中使用%與.format格式化文本方法解析

    python中使用%與.format格式化文本方法解析

    這篇文章主要介紹了python中使用%與.format格式化文本方法解析,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • Python3離線安裝Requests模塊問(wèn)題

    Python3離線安裝Requests模塊問(wèn)題

    這篇文章主要介紹了Python3離線安裝Requests模塊問(wèn)題,本文實(shí)例代碼給大家介紹的非常詳細(xì),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-10-10
  • python3常用的數(shù)據(jù)清洗方法(小結(jié))

    python3常用的數(shù)據(jù)清洗方法(小結(jié))

    這篇文章主要介紹了python3常用的數(shù)據(jù)清洗方法(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 對(duì)Python 窗體(tkinter)文本編輯器(Text)詳解

    對(duì)Python 窗體(tkinter)文本編輯器(Text)詳解

    今天小編就為大家分享一篇對(duì)Python 窗體(tkinter)文本編輯器(Text)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • Python自動(dòng)化辦公之讀取Excel數(shù)據(jù)的實(shí)現(xiàn)

    Python自動(dòng)化辦公之讀取Excel數(shù)據(jù)的實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了如何通過(guò)Python實(shí)現(xiàn)Excel數(shù)據(jù)的讀取,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定幫助,需要的可以參考一下
    2022-05-05
  • Python編程pytorch深度卷積神經(jīng)網(wǎng)絡(luò)AlexNet詳解

    Python編程pytorch深度卷積神經(jīng)網(wǎng)絡(luò)AlexNet詳解

    AlexNet和LeNet的架構(gòu)非常相似。這里我們提供了一個(gè)稍微精簡(jiǎn)版本的AlexNet,去除了當(dāng)年需要兩個(gè)小型GPU同時(shí)運(yùn)算的設(shè)計(jì)特點(diǎn)
    2021-10-10
  • Scrapy 配置動(dòng)態(tài)代理IP的實(shí)現(xiàn)

    Scrapy 配置動(dòng)態(tài)代理IP的實(shí)現(xiàn)

    這篇文章主要介紹了Scrapy 配置動(dòng)態(tài)代理IP的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評(píng)論