91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

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

Swift 的并發(fā)系統(tǒng)并行運(yùn)行多個(gè)任務(wù)

? 來(lái)源:jf_57394773 ? 作者:jf_57394773 ? 2025-11-11 11:33 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

??前言
Swift 內(nèi)置并發(fā)系統(tǒng)的好處之一是它可以更輕松地并行執(zhí)行多個(gè)異步任務(wù),這反過(guò)來(lái)又可以使我們顯著加快可以分解為單獨(dú)部分的操作。

在本文中,讓我們看一下幾種不同的方法,以及這些技術(shù)中的每一種何時(shí)特別有用。

從異步到并發(fā)
首先,假設(shè)我們正在開(kāi)發(fā)某種形式的購(gòu)物應(yīng)用程序來(lái)顯示各種產(chǎn)品,并且我們已經(jīng)實(shí)現(xiàn)了一個(gè)ProductLoader允許我們使用一系列異步 API 加載不同產(chǎn)品集合的應(yīng)用程序,如下所示:

class ProductLoader {
   ...

   func loadFeatured() async throws -> [Product] {
       ...
   }
   
   func loadFavorites() async throws -> [Product] {
       ...
   }
   
   func loadLatest() async throws -> [Product] {
       ...
   }
}
AI寫代碼
盡管大多數(shù)情況下上述每個(gè)方法都可能會(huì)被單獨(dú)調(diào)用,但假設(shè)在我們應(yīng)用程序的某些部分中,我們還希望形成一個(gè)Recommendations包含這三個(gè)ProductLoader方法的所有結(jié)果的組合模型:
extension Product {
   struct Recommendations {
       var featured: [Product]
       var favorites: [Product]
       var latest: [Product]
   }
}
AI寫代碼
一種方法是使用await關(guān)鍵字調(diào)用每個(gè)加載方法,然后使用這些調(diào)用的結(jié)果來(lái)創(chuàng)建我們Recommendations模型的實(shí)例——如下所示:
extension ProductLoader {
   func loadRecommendations() async throws -> Product.Recommendations {
       let featured = try await loadFeatured()
let favorites = try await loadFavorites()
let latest = try await loadLatest()
       
       return Product.Recommendations(
           featured: featured,
           favorites: favorites,
           latest: latest
       )
   }
}
AI寫代碼
上面的實(shí)現(xiàn)確實(shí)有效——然而,即使我們的三個(gè)加載操作都是完全異步的,它們目前正在按順序執(zhí)行,一個(gè)接一個(gè)。因此,盡管我們的頂級(jí)loadRecommendations方法相對(duì)于我們應(yīng)用程序的其他代碼正在并發(fā)執(zhí)行,但實(shí)際上它還沒(méi)有利用并發(fā)來(lái)執(zhí)行其內(nèi)部操作集。
由于我們的產(chǎn)品加載方法不以任何方式相互依賴,因此實(shí)際上沒(méi)有理由按順序執(zhí)行它們,所以讓我們看看如何讓它們完全同時(shí)執(zhí)行。
關(guān)于如何做到這一點(diǎn)的初步想法可能是將上述代碼簡(jiǎn)化為單個(gè)表達(dá)式,這將使我們能夠使用單個(gè)await關(guān)鍵字來(lái)等待我們的每個(gè)操作完成:
extension ProductLoader {
   func loadRecommendations() async throws -> Product.Recommendations {
       try await Product.Recommendations(
           featured: loadFeatured(),
           favorites: loadFavorites(),
           latest: loadLatest()
       )
   }
}
AI寫代碼
然而,即使我們的代碼現(xiàn)在看起來(lái)是并發(fā)的,它實(shí)際上仍會(huì)像以前一樣完全按順序執(zhí)行。
相反,我們需要利用 Swift 的async let綁定來(lái)告訴并發(fā)系統(tǒng)并行執(zhí)行我們的每個(gè)加載操作。使用該語(yǔ)法使我們能夠在后臺(tái)啟動(dòng)異步操作,而無(wú)需我們立即等待它完成。
await如果我們?cè)趯?shí)際使用加載的數(shù)據(jù)時(shí)(即形成模型時(shí))將其與單個(gè)關(guān)鍵字組合Recommendations,那么我們將獲得并行執(zhí)行加載操作的所有好處,而無(wú)需擔(dān)心狀態(tài)管理或數(shù)據(jù)競(jìng)爭(zhēng)之類的事情:
extension ProductLoader {
   func loadRecommendations() async throws -> Product.Recommendations {
       async let featured = loadFeatured()
async let favorites = loadFavorites()
async let latest = loadLatest()
       
       return try await Product.Recommendations(
           featured: featured,
           favorites: favorites,
           latest: latest
       )
   }
}
AI寫代碼
很整齊!因此async let,當(dāng)我們有一組已知的、有限的任務(wù)要執(zhí)行時(shí),它提供了一種同時(shí)運(yùn)行多個(gè)操作的內(nèi)置方法。但如果不是這樣呢?
任務(wù)組
現(xiàn)在假設(shè)我們正在開(kāi)發(fā)一個(gè)ImageLoader可以讓我們通過(guò)網(wǎng)絡(luò)加載圖像的工具。要從給定的 加載單個(gè)圖像URL,我們可以使用如下所示的方法:
class ImageLoader {
   ...

   func loadImage(from url: URL) async throws -> UIImage {
       ...
   }
}
AI寫代碼
為了使一次加載一系列圖像變得簡(jiǎn)單,我們還創(chuàng)建了一個(gè)方便的 API,它接受一個(gè) URL 數(shù)組并異步返回一個(gè)圖像字典,該字典由下載圖像的 URL 鍵控:
extension ImageLoader {
   func loadImages(from urls: [URL]) async throws -> [URL: UIImage] {
       var images = [URL: UIImage]()
       
       for url in urls {
           images[url] = try await loadImage(from: url)
       }
       
       return images
   }
}
AI寫代碼
現(xiàn)在讓我們說(shuō),就像我們ProductLoader之前的工作一樣,我們想讓上面的loadImages方法并發(fā)執(zhí)行,而不是按順序下載每個(gè)圖像(目前是這種情況,因?yàn)槲覀僡wait在調(diào)用時(shí)直接使用loadImage我們的for環(huán)形)。
但是,這次我們將無(wú)法使用async let,因?yàn)槲覀冃枰獔?zhí)行的任務(wù)數(shù)量在編譯時(shí)是未知的。值得慶幸的是,Swift 并發(fā)工具箱中還有一個(gè)工具可以讓我們并行執(zhí)行動(dòng)態(tài)數(shù)量的任務(wù)——任務(wù)組。
要形成一個(gè)任務(wù)組,我們可以調(diào)用withTaskGroup或withThrowingTaskGroup,這取決于我們是否希望可以選擇在我們的任務(wù)中拋出錯(cuò)誤。在這種情況下,我們將選擇后者,因?yàn)槲覀兊牡讓觢oadImage方法是用throws關(guān)鍵字標(biāo)記的。
然后我們將遍歷每個(gè) URL,就像以前一樣,只是這次我們將每個(gè)圖像加載任務(wù)添加到我們的組中,而不是直接等待它完成。相反,我們將await在添加每個(gè)任務(wù)之后單獨(dú)分組結(jié)果,這將允許我們的圖像加載操作完全并發(fā)執(zhí)行:
extension ImageLoader {
   func loadImages(from urls: [URL]) async throws -> [URL: UIImage] {
       try await withThrowingTaskGroup(of: (URL, UIImage).self) { group in
           for url in urls {
               group.addTask{
   let image = try await self.loadImage(from: url)
   return (url, image)
}
           }
           
           var images = [URL: UIImage]()
           
           for try await (url, image) in group {
   images[url] = image
}
           
           return images
       }
   }
}
AI寫代碼

要了解有關(guān)上述for try await語(yǔ)法和一般異步序列的更多信息,請(qǐng)查看“異步序列、流和組合”。

就像使用 時(shí)一樣async let,以我們的操作不會(huì)直接改變?nèi)魏螤顟B(tài)的方式編寫并發(fā)代碼的一個(gè)巨大好處是,這樣做可以讓我們完全避免任何類型的數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題,同時(shí)也不需要我們引入任何鎖定或序列化代碼混合在一起。

await因此,在可能的情況下,讓我們的每個(gè)并發(fā)操作返回一個(gè)完全獨(dú)立的結(jié)果,然后依次返回這些結(jié)果以形成我們的最終數(shù)據(jù)集,這通常是一種很好的方法。

在以后的文章中,我們將更仔細(xì)地研究避免數(shù)據(jù)競(jìng)爭(zhēng)的其他方法(例如通過(guò)使用 Swift 的新actor類型)。

結(jié)論
重要的是要記住,僅僅因?yàn)榻o定的函數(shù)被標(biāo)記為async并不一定意味著它同時(shí)執(zhí)行它的工作。相反,如果這是我們想要做的,我們必須故意讓我們的任務(wù)并行運(yùn)行,這只有在執(zhí)行一組可以獨(dú)立運(yùn)行的操作時(shí)才有意義。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(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)投訴
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    2371

    瀏覽量

    66763
  • SWIFT
    +關(guān)注

    關(guān)注

    0

    文章

    125

    瀏覽量

    24784
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    在睿思芯科靈羽RISC-V服務(wù)器CPU實(shí)現(xiàn)多實(shí)例OpenClaw并發(fā)運(yùn)行

    睿思芯科基于自研“靈羽“系列服務(wù)器CPU實(shí)測(cè)單板承載多實(shí)例OpenClaw并發(fā)運(yùn)行。基于標(biāo)準(zhǔn)Linux+Docker環(huán)境并行響應(yīng)不同業(yè)務(wù)需求,為企業(yè)未來(lái)的大規(guī)模Al Agent托管打開(kāi)了更優(yōu)單位算力成本的新路
    的頭像 發(fā)表于 02-11 09:37 ?473次閱讀
    在睿思芯科靈羽RISC-V服務(wù)器CPU實(shí)現(xiàn)多實(shí)例OpenClaw<b class='flag-5'>并發(fā)運(yùn)行</b>

    一文說(shuō)透了如何實(shí)現(xiàn)單片機(jī)的多任務(wù)并發(fā)

    任務(wù)并發(fā)。 一、任務(wù)調(diào)度 任務(wù)調(diào)度是多任務(wù)并發(fā)中一個(gè)非常重要的概念。它指的是如何在
    發(fā)表于 01-06 06:46

    解析Linux的進(jìn)程、線程和協(xié)程

    允許在單個(gè)線程內(nèi)實(shí)現(xiàn)多個(gè)協(xié)程的并發(fā)執(zhí)行。協(xié)程在執(zhí)行過(guò)程中可以主動(dòng)掛起和恢復(fù),這使得編寫高效的異步代碼變得更加容易。協(xié)程通常用于處理I/O密集型任務(wù),能夠提高程序的響應(yīng)性能。 協(xié)程的特點(diǎn)包括: (1
    發(fā)表于 12-22 11:00

    高性能網(wǎng)絡(luò)存儲(chǔ)設(shè)計(jì):NVMe-oF IP的實(shí)現(xiàn)探討

    Initiator 并發(fā)訪問(wèn)支持(Multi-Initiator Sharing) 系統(tǒng)從協(xié)議棧到調(diào)度機(jī)制均支持多個(gè) Initiator(多個(gè)客戶端)同時(shí)訪問(wèn)單個(gè)Target: ?每
    發(fā)表于 12-19 18:45

    并行智能體:洞察復(fù)雜系統(tǒng)的 14 種并發(fā)設(shè)計(jì)模式

    在AI智能體的世界中,速度、質(zhì)量和可靠性不僅僅是特性,它們是必備條件。一個(gè)單一、順序執(zhí)行的智能體可能速度慢、容易出錯(cuò),并且解決問(wèn)題的能力有限。解決方案是采用并行思維:設(shè)計(jì)一個(gè)系統(tǒng),讓多個(gè)智能體、流程
    的頭像 發(fā)表于 12-02 15:07 ?595次閱讀
    <b class='flag-5'>并行</b>智能體:洞察復(fù)雜<b class='flag-5'>系統(tǒng)</b>的 14 種<b class='flag-5'>并發(fā)</b>設(shè)計(jì)模式

    Linux多線程對(duì)比單線程的優(yōu)勢(shì)

    在Linux系統(tǒng)中,線程是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。線程被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)行單位。一個(gè)進(jìn)程可以擁有多個(gè)線程,這些線
    發(fā)表于 12-01 06:11

    【HZ-T536開(kāi)發(fā)板免費(fèi)體驗(yàn)】—— linux創(chuàng)建線程

    的執(zhí)行任務(wù)成為單線程。多線程是程序中包含多個(gè)執(zhí)行流,在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來(lái)執(zhí)行不同的任務(wù)。 多線程提高了CPU的使用鹵率。
    發(fā)表于 09-01 21:31

    Task任務(wù):LuatOS實(shí)現(xiàn)“任務(wù)級(jí)并發(fā)”的核心引擎

    Task任務(wù)通過(guò)其強(qiáng)大的并發(fā)處理能力,使LuatOS能夠在單線程環(huán)境中模擬多線程執(zhí)行,通過(guò)協(xié)程的掛起與恢復(fù)機(jī)制,實(shí)現(xiàn)任務(wù)級(jí)的并行操作,顯著提升系統(tǒng)
    的頭像 發(fā)表于 08-28 13:49 ?509次閱讀
    Task<b class='flag-5'>任務(wù)</b>:LuatOS實(shí)現(xiàn)“<b class='flag-5'>任務(wù)</b>級(jí)<b class='flag-5'>并發(fā)</b>”的核心引擎

    第三屆大會(huì)回顧第3期 | FFRT并發(fā)框架在OpenHarmony中的設(shè)計(jì)與實(shí)踐

    ,特別是在多核處理器上,可以顯著提高程序的運(yùn)行速度和整體性能,從而改善用戶體驗(yàn)。OpenHarmony的FFRT并發(fā)編程模型為開(kāi)發(fā)者提供了構(gòu)建異步并發(fā)任務(wù)的能力,以更高效地開(kāi)發(fā)和管理
    的頭像 發(fā)表于 06-21 16:53 ?1271次閱讀
    第三屆大會(huì)回顧第3期 | FFRT<b class='flag-5'>并發(fā)</b>框架在OpenHarmony中的設(shè)計(jì)與實(shí)踐

    同步任務(wù)開(kāi)發(fā)指導(dǎo)

    同步任務(wù)是指在多個(gè)線程之間協(xié)調(diào)執(zhí)行的任務(wù),其目的是確保多個(gè)任務(wù)按照一定的順序和規(guī)則執(zhí)行,例如使用鎖來(lái)防止數(shù)據(jù)競(jìng)爭(zhēng)。 同步
    發(fā)表于 06-19 07:57

    I/O密集型任務(wù)開(kāi)發(fā)指導(dǎo)

    能力,而在于I/O操作的速度和效率。這種任務(wù)通常需要頻繁地進(jìn)行磁盤讀寫、網(wǎng)絡(luò)通信等操作。此處以頻繁讀寫系統(tǒng)文件來(lái)模擬I/O密集型并發(fā)任務(wù)的處理。 定義
    發(fā)表于 06-19 07:19

    鴻蒙5開(kāi)發(fā)寶藏案例分享---應(yīng)用并發(fā)設(shè)計(jì)

    1:耗時(shí)任務(wù)并發(fā)——圖片解碼加速 痛點(diǎn) :主線程解碼4K圖片導(dǎo)致界面卡死 // 步驟1:定義并發(fā)函數(shù) @Concurrent function decodeImage(imageData
    發(fā)表于 06-12 16:19

    CRC16-MODBUS+手算+移位運(yùn)算+C程序+并行運(yùn)

    CRC16-MODBUS+手算+移位運(yùn)算+C程序+并行運(yùn)
    發(fā)表于 04-22 18:23 ?0次下載

    讀懂極易并行計(jì)算:定義、挑戰(zhàn)與解決方案

    GPU經(jīng)常與人工智能同時(shí)提及,其中一個(gè)重要原因在于AI與3D圖形處理本質(zhì)上屬于同一類問(wèn)題——它們都適用極易并行計(jì)算。什么是極易并行計(jì)算?極易并行計(jì)算指的是符合以下特征的計(jì)算任務(wù)
    的頭像 發(fā)表于 04-17 09:11 ?818次閱讀
    讀懂極易<b class='flag-5'>并行</b>計(jì)算:定義、挑戰(zhàn)與解決方案

    如何使用S32DS在MPC5775B中并行運(yùn)行兩個(gè)內(nèi)核(core0 和 core2)?

    誰(shuí)能幫我了解如何使用 S32DS 在 MPC5775B 中并行運(yùn)行兩個(gè)內(nèi)核(core0 和 core2)?
    發(fā)表于 03-31 06:27