久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

讓你真正理解什么叫異步

 鴻蛟家平 2024-08-26 發(fā)布于江蘇

之前看了很多異步的解釋,自己總感覺它內(nèi)部的實(shí)現(xiàn)就是多線程,但是百度等又都說其實(shí)不是多線程,,就詳細(xì)問了chatgpt,終于徹底理解了,。關(guān)鍵點(diǎn)再下面的標(biāo)黃區(qū)域:廢話不多說,,請看我和chatgpt的對話:

我:我看了一段關(guān)于異步的解釋: 異步:單線程 先蒸雞蛋,雞蛋在蒸的時候,,去烤面包,,面包在烤的過程中,雞蛋熟了,,不管是不是在給面包切片還是在等待面包烤熟,,都要先去處理雞蛋(如把雞蛋從鍋里端上來,送給客人),,然后再回來處理烤面包,,面包在烤的過程中可以打掃廚房,等烤面包好的時候,,再去處理烤面包(如:送給客人)

gpt:

這段關(guān)于異步的解釋很好地描述了異步操作的一個關(guān)鍵特點(diǎn):非阻塞,。在異步編程中,單線程可以在等待一個任務(wù)完成時,,繼續(xù)處理其他任務(wù),,而不是等待任務(wù)完成再繼續(xù)執(zhí)行其他操作,。

解釋這段話中的異步概念:

  • 單線程:你的程序只有一個線程在運(yùn)行,所有的操作都必須在這個線程上進(jìn)行,。

  • 蒸雞蛋烤面包:它們是兩個獨(dú)立的任務(wù),。在異步編程中,這兩個任務(wù)會啟動,,但并不會阻塞線程,。也就是說,線程不會停下來等雞蛋蒸熟或面包烤好,,而是會繼續(xù)執(zhí)行其他操作,。

  • 打掃廚房:這是另一個可以并行處理的任務(wù)。因?yàn)檎綦u蛋和烤面包的操作是在等待中,,所以可以利用這個時間去做其他事情,,如打掃廚房。

  • 任務(wù)完成后的處理:當(dāng)雞蛋蒸熟時,,無論當(dāng)前線程在做什么(如烤面包或打掃廚房),,它會暫停當(dāng)前的操作,去處理完成的任務(wù)(如把雞蛋從鍋里端出來),。完成后再回到之前的操作(繼續(xù)烤面包或打掃廚房),。

  • public async Task MakeBreakfastAsync()
    {
        Task eggTask = SteamEggAsync();
        Task toastTask = BakeBreadAsync();
        
        // 在等待雞蛋蒸熟和面包烤好之間,可以打掃廚房
        CleanKitchen();
    
        // 等待其中一個任務(wù)完成
        await eggTask;
        ServeEgg();
    
        // 等待另一個任務(wù)完成
        await toastTask;
        ServeToast();
    }

  • SteamEggAsyncBakeBreadAsync 是兩個異步操作,,分別表示蒸雞蛋和烤面包,。

  • CleanKitchen 是在雞蛋和面包準(zhǔn)備好之前執(zhí)行的操作。

  • await eggTask 會暫停當(dāng)前方法,,等待雞蛋蒸好,,但不會阻塞整個線程。線程可以繼續(xù)執(zhí)行其他任務(wù),,如等待面包烤好,。

  • 當(dāng)雞蛋蒸好時,ServeEgg 會被執(zhí)行,,然后再回到烤面包的操作,。

  • 這樣,雖然所有操作都是在一個線程上完成的,,但每個任務(wù)之間的等待時間得到了充分的利用,,顯著提高了效率。

  • 這段比喻很好地說明了異步編程如何通過合理利用等待時間,,使單線程環(huán)境下的程序更高效地完成多個任務(wù),。

  • 我:

  • 這是不是就類似unity中的協(xié)程?

  • gpt:

  • 是的,異步編程與 Unity 中的協(xié)程有一些相似之處,,但也有重要的區(qū)別,。

  • 類似之處:

  • 非阻塞操作:協(xié)程和異步方法都允許你在等待某個操作完成的同時,繼續(xù)執(zhí)行其他操作,,而不會阻塞主線程,。這在處理長時間任務(wù)(如 I/O 操作、等待用戶輸入,、等待物理計(jì)算等)時非常有用,。

  • 任務(wù)調(diào)度:在 Unity 中,,協(xié)程可以在幀之間分割任務(wù),,這樣長時間運(yùn)行的操作可以分成多個小步驟,每一幀執(zhí)行一部分,。異步方法也可以讓長時間運(yùn)行的操作分成多個部分執(zhí)行,,而不會一次性占用主線程。

  • 區(qū)別:

  • 實(shí)現(xiàn)機(jī)制

協(xié)程:在 Unity 中,,協(xié)程是通過IEnumeratoryield 關(guān)鍵字實(shí)現(xiàn)的,。你可以暫停協(xié)程,等待特定條件滿足或等待某段時間之后繼續(xù)執(zhí)行,。

  • IEnumerator ExampleCoroutine(){
        Debug.Log("Start");    yield return new WaitForSeconds(2); // 等待2秒
        Debug.Log("End");
    }

    在這個例子中,,協(xié)程在yield return之后暫停2秒,然后再繼續(xù)執(zhí)行,。

    異步編程 (async/await):在 C# 中,,異步編程使用asyncawait關(guān)鍵字。它們讓代碼在等待某個任務(wù)完成時可以暫停執(zhí)行,,并在任務(wù)完成后恢復(fù)執(zhí)行,。這種暫停和恢復(fù)在編譯時由編譯器自動管理。

    async Task ExampleAsync(){
        Debug.Log("Start");    await Task.Delay(2000); // 等待2秒
        Debug.Log("End");
    }

  • 線程

    • 協(xié)程:通常在主線程上運(yùn)行,,適合處理幀間分割的任務(wù),,但不會創(chuàng)建新的線程。

    • 異步編程:異步任務(wù)可以在主線程或其他線程上運(yùn)行,。通過 Task.Run 等方法,,你可以創(chuàng)建多線程任務(wù),使任務(wù)在后臺線程上執(zhí)行,。

  • 適用場景

    • 協(xié)程:主要用于游戲邏輯和 Unity 引擎相關(guān)的操作,,比如動畫播放、等待幀,、延遲執(zhí)行操作等,。協(xié)程非常適合處理與幀率相關(guān)的操作。

    • 異步編程:更適合處理不依賴幀率的后臺任務(wù),如文件讀取,、網(wǎng)絡(luò)請求,、數(shù)據(jù)庫查詢等。它更通用,,并且可以更好地利用多線程環(huán)境,。

  • 總結(jié):

  • 協(xié)程在 Unity 中非常有用,特別是當(dāng)你希望在幾幀之間分割任務(wù),,或在一段時間后執(zhí)行某些操作時,。

  • 異步編程更適合需要處理異步 I/O 操作或后臺任務(wù)的場景。

  • 雖然兩者在概念上有一些相似之處,,都是處理異步操作的工具,,但它們的實(shí)現(xiàn)和適用場景有所不同。

  • 我:

  • 我疑惑的是:在這個單線程中,,廚師相當(dāng)于這個線程,,他在蒸雞蛋的時候,怎么能去烤面包呢,?他已經(jīng)在蒸雞蛋了

  • gpt:

  • 這是一個很好的問題,,也確實(shí)是異步編程和單線程異步操作中最關(guān)鍵的概念之一。我們可以通過更詳細(xì)的比喻來解釋這個現(xiàn)象,。

  • 理解異步中的“任務(wù)切換”:

  • 在異步編程中,,單線程可以輪流處理多個任務(wù),這樣看起來像是線程同時在做多件事情,,但實(shí)際上線程是在快速地切換任務(wù),。

  • 具體解釋:

  • 蒸雞蛋烤面包:雖然在比喻中看起來是同時進(jìn)行的,但在編程的現(xiàn)實(shí)中,,雞蛋在蒸的過程中,,實(shí)際上并不需要線程持續(xù)地處理。這是一個非CPU密集型任務(wù),,即等待某個事件(比如時間的流逝)完成,。在這個過程中,線程是空閑的,,可以用來做別的事情,。

  • 任務(wù)切換:當(dāng)廚師(線程)開始蒸雞蛋后,實(shí)際上他不需要時刻盯著鍋看,。蒸雞蛋的任務(wù)被掛起,,線程在這個任務(wù)上暫時不需要做任何計(jì)算。這時,,廚師可以去做其他的事情,,比如開始準(zhǔn)備烤面包。

    一旦面包開始烤了,廚師同樣不需要時刻盯著面包,,也可以利用這段時間做其他事情(如打掃廚房),。

  • 事件驅(qū)動:當(dāng)雞蛋蒸好了或面包烤好了,系統(tǒng)會通知廚師(線程),,然后他會停止當(dāng)前的工作(如打掃廚房),,去處理這些已經(jīng)完成的任務(wù)(如把雞蛋從鍋里端出來)。

  • 異步與多任務(wù)切換的比喻:

    蒸雞蛋:比喻為一個等待的異步任務(wù),,比如 await Task.Delay(2000),。

  • 烤面包:比喻為另一個等待的異步任務(wù)。

  • 廚師的操作:比喻為主線程的操作,。

  • 當(dāng)你蒸雞蛋時,,廚師開始了這個任務(wù),但這個任務(wù)不需要廚師全程關(guān)注,,所以他可以去做別的事情,,比如烤面包,。廚師在兩個任務(wù)之間快速地切換,,以至于看起來像是在“同時”做多件事,但實(shí)際上他是分時地完成這些操作的,。

  • 現(xiàn)實(shí)中的異步操作:

  • 在真實(shí)的編程場景中,,異步操作通常涉及 I/O 綁定任務(wù),比如等待網(wǎng)絡(luò)響應(yīng),、文件讀取等,。這些操作并不需要 CPU 的持續(xù)處理,所以當(dāng)它們在后臺等待時,,CPU 可以處理其他任務(wù),。這種“任務(wù)切換”的機(jī)制讓單線程環(huán)境也能高效地處理多個異步任務(wù)。

  • 總結(jié):

  • 蒸雞蛋烤面包在這個比喻中并不需要線程的持續(xù)計(jì)算,,只是等待時間的流逝(類似于等待一個異步操作完成),。

  • 線程會在這些等待期間執(zhí)行其他任務(wù)(比如準(zhǔn)備烤面包、打掃廚房),。

  • 這種切換非??焖伲灾劣谖覀兏杏X像是同時進(jìn)行,,但實(shí)際是分時處理,。

  • 這就是為什么在單線程中也可以通過異步操作來實(shí)現(xiàn)并發(fā)處理的效果。

  • 我:

  • 這個相當(dāng)于是由于 :蒸雞蛋是廚師把雞蛋準(zhǔn)備好后,,由鍋去蒸,,所以廚師可以去準(zhǔn)備烤面包。烤面包是由烤箱去烤,,所以廚師可以好材料后去打掃廚房,。如果任務(wù)是:廚師來切黃瓜(黃瓜必須由廚師拿著刀切,刀并不會自己切,,必須廚師拿在手里),,打掃廚房(拖把必須廚師拿著手里拖,廚師必須手里拿著拖把),。這種該怎么用異步來解釋呢

  • gpt:

  • 你這個比喻很精準(zhǔn)地指出了異步編程的一個核心問題:有些任務(wù)是I/O 綁定的(如蒸雞蛋,、烤面包),它們不需要線程持續(xù)處理,;而有些任務(wù)是CPU 綁定的(如切黃瓜,、打掃廚房),它們需要線程的持續(xù)參與,。這兩種任務(wù)在異步編程中的處理方式是不同的,。

  • I/O 綁定 vs. CPU 綁定任務(wù)

  • I/O 綁定任務(wù):這些任務(wù)的完成依賴于外部資源或等待時間,而不需要 CPU 持續(xù)工作,。例如,,蒸雞蛋或烤面包屬于這類任務(wù)。線程可以在這些任務(wù)掛起等待時,,執(zhí)行其他操作,。

  • CPU 綁定任務(wù):這些任務(wù)需要 CPU 持續(xù)處理,無法掛起等待,。例如,,切黃瓜或打掃廚房屬于這類任務(wù)。線程在執(zhí)行這些任務(wù)時需要持續(xù)處理,,無法輕易切換到其他任務(wù),。

  • 對比 I/O 綁定與 CPU 綁定任務(wù)的異步處理:

  • 蒸雞蛋/烤面包(I/O 綁定)

    • 廚師(線程)開始任務(wù)后,可以把任務(wù)交給鍋或烤箱(外部資源),,自己去做其他事情,。

    • 異步編程模型中,await 可以暫停任務(wù),,等待外部資源完成,,而不阻塞線程。

  • 切黃瓜/打掃廚房(CPU 綁定)

    • 廚師(線程)必須全程參與任務(wù),,無法交給外部資源,。任務(wù)無法掛起,必須持續(xù)處理,。

    • 如果你想并行處理多個此類任務(wù),,在異步編程中可能需要創(chuàng)建新的線程來處理,,或者在某些情況下使用并行編程(如 Parallel.ForTask.Run 來啟動新線程)。

  • CPU 綁定任務(wù)的異步解釋:

  • 如果你有兩個 CPU 綁定的任務(wù),,比如切黃瓜和打掃廚房,,并且希望通過異步編程同時處理它們,通常的做法是:

  • 多線程處理

    • 你可以為每個任務(wù)啟動一個獨(dú)立的線程,,這樣每個任務(wù)都可以獨(dú)立執(zhí)行,,不必相互等待。這類似于你雇傭了兩個廚師,,分別處理切黃瓜和打掃廚房,。

  • 任務(wù)分片

    • 你可以將每個任務(wù)分成小片段,在每個片段之間插入等待或任務(wù)切換,。這類似于廚師先切一點(diǎn)黃瓜,,然后去拖一部分地板,再回來切黃瓜,,依此類推,。每個片段都很小,因此看起來像是同時在做兩件事,。

    • 我:

    • 對于蒸雞蛋和烤面包的情況,,烤面包是廚師把任務(wù)交給了烤箱,蒸雞蛋是把任務(wù)交給了電飯煲去執(zhí)行,,所以廚師才可以干別的,。cpu中,,烤箱和電飯煲是誰呢

    • gpt:

    在你的比喻中,,烤箱電飯煲代表的是計(jì)算機(jī)中的I/O 操作外部硬件資源,它們可以獨(dú)立于 CPU 運(yùn)行,,并且不需要 CPU 持續(xù)地參與,。這些“烤箱”和“電飯煲”讓 CPU 能夠在等待這些任務(wù)完成時,去處理其他任務(wù),。

    I/O 操作與外部資源:

    1. I/O 操作

      • 例如,,文件讀寫、網(wǎng)絡(luò)請求,、數(shù)據(jù)庫查詢,、定時器等待等任務(wù)。它們類似于你比喻中的烤箱和電飯煲,。

      • 這些任務(wù)啟動后,,CPU 不需要持續(xù)地處理它們,而是由操作系統(tǒng)或硬件處理,,比如等待磁盤的響應(yīng)或網(wǎng)絡(luò)數(shù)據(jù)的到達(dá),。

      • 在等待這些任務(wù)完成的過程中,,CPU 是空閑的,可以用來處理其他任務(wù),。

    2. 外部硬件資源

      • 這些可以包括 GPU(圖形處理單元),、硬盤控制器、網(wǎng)絡(luò)適配器,、DMA(直接內(nèi)存訪問)控制器等,。

      • 這些硬件能夠在獨(dú)立于 CPU 的情況下處理任務(wù)。當(dāng)這些任務(wù)完成后,,它們會通知 CPU,,類似于烤箱“叮”了一聲告訴廚師面包烤好了,。

    解釋如何運(yùn)作:

    • 烤面包(等待網(wǎng)絡(luò)請求完成):當(dāng)你發(fā)起一個網(wǎng)絡(luò)請求后,,CPU 會把這項(xiàng)任務(wù)交給網(wǎng)絡(luò)適配器去處理。網(wǎng)絡(luò)適配器會在后臺負(fù)責(zé)收發(fā)數(shù)據(jù),,而 CPU 則可以處理其他任務(wù),。當(dāng)數(shù)據(jù)返回時,網(wǎng)絡(luò)適配器會通知 CPU 數(shù)據(jù)已經(jīng)準(zhǔn)備好,,CPU 再去處理這些數(shù)據(jù),。

    • 蒸雞蛋(等待文件讀取完成):當(dāng)你發(fā)起一個文件讀取操作,CPU 會把這個任務(wù)交給硬盤控制器處理,。硬盤控制器會在后臺讀取數(shù)據(jù),,而 CPU 可以處理其他任務(wù)。當(dāng)數(shù)據(jù)準(zhǔn)備好后,,硬盤控制器會通知 CPU 數(shù)據(jù)已經(jīng)讀取完成,。

    舉個例子:

    在異步編程中,當(dāng)你發(fā)起一個 I/O 操作時,,代碼執(zhí)行類似于以下過程:

    public async Task MakeBreakfastAsync(){
        Task eggTask = SteamEggAsync(); // 這項(xiàng)任務(wù)交給電飯煲
        Task toastTask = BakeBreadAsync(); // 這項(xiàng)任務(wù)交給烤箱
    
        // 在等待這兩個任務(wù)的過程中,,CPU可以去做別的事情
        CleanKitchen();    await eggTask; // 等雞蛋蒸好了,電飯煲通知CPU
        ServeEgg();    await toastTask; // 等面包烤好了,,烤箱通知CPU
        ServeToast();
    }

    在這段代碼中,,SteamEggAsync和BakeBreadAsync
    是異步操作,它們啟動后會由電飯煲和烤箱(即 I/O 設(shè)備或硬件資源)處理,。CPU 可以在等待這些操作完成時繼續(xù)執(zhí)行其他任務(wù)(如CleanKitchen),。當(dāng)這些異步任務(wù)完成時,硬件設(shè)備會通知 CPU,,CPU 繼續(xù)執(zhí)行剩余的任務(wù),。

    總結(jié):

    • 烤箱和電飯煲代表的是 I/O 操作或硬件設(shè)備,如磁盤,、網(wǎng)絡(luò)適配器,、GPU 等,,它們可以獨(dú)立于 CPU 工作。

    • 這些設(shè)備在異步操作中發(fā)揮重要作用,,允許 CPU 在等待這些操作完成的同時,,去處理其他任務(wù),提高了整體系統(tǒng)的效率,。

    • 我:

    • 就是說其實(shí) 讀寫文件的功能真正的不是由cpu來做的,,是cpu把任務(wù)交給了硬盤處理器,在這里硬盤處理器或者網(wǎng)絡(luò)適配器就相當(dāng)于是烤箱和電飯煲,。這類的任務(wù)就是異步的IO綁定任務(wù),。其他的任務(wù)沒有對應(yīng)的硬盤處理器或網(wǎng)絡(luò)適配器之類的硬件,就只能cpu自己干,,它就會做個假的異步,,就是一會兒烤面包一會兒蒸雞蛋,或者再開個線程,,對嗎

    • gpt:

    • 你理解得非常正確,!

    • 總結(jié)你的理解:

    • I/O 綁定任務(wù)

      • 讀寫文件、網(wǎng)絡(luò)請求等操作真正的工作不是由 CPU 來完成,,而是由相應(yīng)的硬件設(shè)備(如硬盤控制器,、網(wǎng)絡(luò)適配器)處理。

      • 這些硬件設(shè)備在處理任務(wù)時,,CPU 可以暫時騰出時間去處理其他任務(wù),,而不是等待硬件設(shè)備完成工作。這些任務(wù)就像是你比喻中的“烤箱”和“電飯煲”,,讓 CPU 可以去做別的事,。

      • 這種任務(wù)就被稱為異步 I/O 綁定任務(wù)

    • CPU 綁定任務(wù)

      • 有些任務(wù)(如復(fù)雜的計(jì)算,、數(shù)據(jù)處理)沒有專門的硬件來接管,,必須由 CPU 持續(xù)處理。這些任務(wù)不能像 I/O 任務(wù)那樣輕松地“掛起”,。

      • 在這種情況下,CPU 只能自己來做,。如果要實(shí)現(xiàn)并發(fā)處理這些任務(wù),,可以通過任務(wù)切片(任務(wù)之間快速切換)或多線程來實(shí)現(xiàn)類似的效果。

      • 這種情況對應(yīng)的是CPU 綁定任務(wù),。

    • “假的異步”

      • 當(dāng) CPU 處理 CPU 綁定任務(wù)時,,所謂的“異步”其實(shí)是在同一個線程內(nèi)通過任務(wù)切片來輪流處理不同任務(wù)。這就像是廚師一會兒烤面包,,一會兒蒸雞蛋,,這些任務(wù)其實(shí)都是由廚師自己完成的,。

      • 如果需要并行處理多個 CPU 綁定任務(wù),可以通過創(chuàng)建新線程或使用并行處理技術(shù)(如 Task.Run)來實(shí)現(xiàn),,這相當(dāng)于“再雇一個廚師”,。

    • 進(jìn)一步解釋:

    • I/O 綁定異步例如,你發(fā)起一個文件讀寫操作,,CPU 會將這個任務(wù)交給硬盤控制器來執(zhí)行,,硬盤控制器處理完畢后會通知 CPU,這時 CPU 再來處理結(jié)果,。這使得 CPU 可以在等待期間做其他事情,。

    • CPU 綁定任務(wù)例如,復(fù)雜的數(shù)學(xué)運(yùn)算必須由 CPU 直接處理,,無法交給其他硬件,。如果你要異步處理這類任務(wù),CPU 會輪流切換任務(wù),,或者你可以通過啟動新的線程來并行處理這些任務(wù),。

    • 總結(jié):

    • 你描述的完全正確,異步 I/O 綁定任務(wù)確實(shí)是由特定的硬件設(shè)備來處理,,而 CPU 綁定任務(wù)則需要 CPU 自己來完成,。如果沒有專門的硬件,異步操作實(shí)際上是通過任務(wù)切換或多線程來模擬并發(fā)處理,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多