日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Golang異步編程方式和技巧

來源: 責編: 時間:2024-04-24 17:34:54 155觀看
導讀作者 | zvalhuGolang基于多線程、協程實現,與生俱來適合異步編程,當我們遇到那種需要批量處理且耗時的操作時,傳統的線性執行就顯得吃力,這時就會想到異步并行處理。下面介紹一些異步編程方式和技巧。一、使用方式1.最簡

作者 | zvalhucYh28資訊網——每日最新資訊28at.com

Golang基于多線程、協程實現,與生俱來適合異步編程,當我們遇到那種需要批量處理且耗時的操作時,傳統的線性執行就顯得吃力,這時就會想到異步并行處理。下面介紹一些異步編程方式和技巧。cYh28資訊網——每日最新資訊28at.com

cYh28資訊網——每日最新資訊28at.com

一、使用方式

1.最簡單的最常用的方式:使用go關鍵詞

func main() { go func() {  fmt.Println("hello world1") }() go func() {  fmt.Println("hello world2") }()}

或者:cYh28資訊網——每日最新資訊28at.com

func main() { go Announce("hello world1") go Announce("hello world2")}func Announce(message string) { fmt.Println(message)}

使用匿名函數傳遞參數cYh28資訊網——每日最新資訊28at.com

data := "Hello, World!"go func(msg string) {      // 使用msg進行異步任務邏輯處理      fmt.Println(msg)}(data)

這種方式不需要考慮返回值問題,如果要考慮返回值,可以使用下面的方式。cYh28資訊網——每日最新資訊28at.com

2.通過goroutine和channel來實現

ch := make(chan int, 1) // 創建一個帶緩沖的channel// ch := make(chan int, 0) // 創建一個無緩沖的channelgo func() {    // 異步任務邏輯    ch <- result // 將結果發送到channel    // 異步任務邏輯    close(ch) // 關閉channel,表示任務完成}()// 在需要的時候從channel接收結果result := <-ch

3.使用sync.WaitGroup

sync.WaitGroup用于等待一組協程完成其任務。通過Add()方法增加等待的協程數量,Done()方法標記協程完成,Wait()方法阻塞直到所有協程完成。cYh28資訊網——每日最新資訊28at.com

var wg sync.WaitGroup// 啟動多個協程for i := 0; i < 5; i++ {    wg.Add(1)    go func(index int) {        defer wg.Done()        // 異步任務邏輯    }(i)}// 等待所有協程完成wg.Wait()

4.使用errgroup實現協程組的錯誤處理

如果想簡單獲取協程返回的錯誤,errgroup包很適合,errgroup包是Go語言標準庫中的一個實用工具,用于管理一組協程并處理它們的錯誤。可以使用errgroup.Group結構來跟蹤和處理協程組的錯誤。cYh28資訊網——每日最新資訊28at.com

var eg errgroup.Groupfor i := 0; i < 5; i++ {    eg.Go(func() error {     return errors.New("error")    })    eg.Go(func() error {     return nil    })}if err := eg.Wait(); err != nil {    // 處理錯誤}

二、一些使用技巧

1.使用channel的range和close操作

range操作可以在接收通道上迭代值,直到通道關閉。可以使用close函數關閉通道,以向接收方指示沒有更多的值。cYh28資訊網——每日最新資訊28at.com

ch := make(chan int)go func() {    for i := 0; i < 5; i++ {        ch <- i // 發送值到通道    }    close(ch) // 關閉通道}()// 使用range迭代接收通道的值for val := range ch {    // 處理接收到的值}

2.使用select語句實現多個異步操作的等待

ch1 := make(chan int)ch2 := make(chan string)go func() {    // 異步任務1邏輯    ch1 <- result1}()go func() {    // 異步任務2邏輯    ch2 <- result2}()// 在主goroutine中等待多個異步任務完成select {case res1 := <-ch1:    // 處理結果1case res2 := <-ch2:    // 處理結果2}

3.使用select和time.After()實現超時控制

如果需要在異步操作中設置超時,可以使用select語句結合time.After()函數實現。cYh28資訊網——每日最新資訊28at.com

ch := make(chan int)go func() {    // 異步任務邏輯    time.Sleep(2 * time.Second)    ch <- result}()// 設置超時時間select {case res := <-ch:    // 處理結果case <-time.After(3 * time.Second):    // 超時處理}

4.使用select和time.After()實現超時控制

如果需要在異步操作中設置超時,可以使用select語句結合time.After()函數實現。cYh28資訊網——每日最新資訊28at.com

ch := make(chan int)go func() {    // 異步任務邏輯    time.Sleep(2 * time.Second)    ch <- result}()// 設置超時時間select {case res := <-ch:    // 處理結果case <-time.After(3 * time.Second):    // 超時處理}

5.使用time.Tick()和time.After()進行定時操作

time.Tick()函數返回一個通道,定期發送時間值,可以用于執行定時操作。time.After()函數返回一個通道,在指定的時間后發送一個時間值。cYh28資訊網——每日最新資訊28at.com

tick := time.Tick(1 * time.Second) // 每秒執行一次操作for {    select {    case <-tick:        // 執行定時操作    }}select {case <-time.After(5 * time.Second):    // 在5秒后執行操作}

6.使用sync.Mutex或sync.RWMutex進行并發安全訪問

當多個協程并發訪問共享數據時,需要確保數據訪問的安全性。sync.Mutex和sync.RWMutex提供了互斥鎖和讀寫鎖,用于在訪問共享資源之前進行鎖定,以避免數據競爭。sync.RWMutex是一種讀寫鎖,可以在多個協程之間提供對共享資源的并發訪問控制。多個協程可以同時獲取讀鎖,但只有一個協程可以獲取寫鎖。cYh28資訊網——每日最新資訊28at.com

var mutex sync.Mutexvar data int// 寫操作,使用互斥鎖保護數據mutex.Lock()data = 123mutex.Unlock()// 讀操作,使用讀鎖保護數據//RLock()加讀鎖時,如果存在寫鎖,則無法加讀鎖;當只有讀鎖或者沒有鎖時,可以加讀鎖,讀鎖可以加載多個mutex.RLock()value := datamutex.RUnlock()var rwMutex sync.RWMutexvar sharedData map[string]string// 讀操作,使用rwMutex.RLock讀鎖保護數據func readData(key string) string {    rwMutex.RLock()    defer rwMutex.RUnlock()    return sharedData[key]}// 寫操作,使用rwMutex.Lock寫鎖保護數據func writeData(key, value string) {    rwMutex.Lock()    defer rwMutex.Unlock()    sharedData[key] = value}

注意:sync.Mutex 的鎖是不可以嵌套使用的 sync.RWMutex 的 RLock()是可以嵌套使用的 sync.RWMutex 的 mu.Lock() 是不可以嵌套的 sync.RWMutex 的 mu.Lock() 中不可以嵌套 mu.RLock()cYh28資訊網——每日最新資訊28at.com

7.使用sync.Cond進行條件變量控制

sync.Cond是一個條件變量,用于在協程之間進行通信和同步。它可以在指定的條件滿足之前阻塞等待,并在條件滿足時喚醒等待的協程。cYh28資訊網——每日最新資訊28at.com

var cond = sync.NewCond(&sync.Mutex{})var ready boolgo func() {    // 異步任務邏輯    ready = true    // 通知等待的協程條件已滿足    cond.Broadcast()}()// 在某個地方等待條件滿足cond.L.Lock()for !ready {    cond.Wait()}cond.L.Unlock()

8.使用sync.Pool管理對象池

sync.Pool是一個對象池,用于緩存和復用臨時對象,可以提高對象的分配和回收效率。cYh28資訊網——每日最新資訊28at.com

type MyObject struct {    // 對象結構}var objectPool = sync.Pool{    New: func() interface{} {        // 創建新對象        return &MyObject{}    },}// 從對象池獲取對象obj := objectPool.Get().(*MyObject)// 使用對象// 將對象放回對象池objectPool.Put(obj)

9.使用sync.Once實現只執行一次的操作

sync.Once用于確保某個操作只執行一次,無論有多少個協程嘗試執行它,常用于初始化或加載資源等場景。cYh28資訊網——每日最新資訊28at.com

var once sync.Oncevar resource *Resourcefunc getResource() *Resource {    once.Do(func() {        // 執行初始化資源的操作,僅執行一次        resource = initResource()    })    return resource}// 在多個協程中獲取資源go func() {    res := getResource()    // 使用資源}()go func() {    res := getResource()    // 使用資源}()

10.使用sync.Once和context.Context實現資源清理

可以結合使用sync.Once和context.Context來確保在多個協程之間只執行一次資源清理操作,并在取消或超時時進行清理。cYh28資訊網——每日最新資訊28at.com

var once sync.Oncefunc cleanup() {    // 執行資源清理操作}func doTask(ctx context.Context) {    go func() {        select {        case <-ctx.Done():            once.Do(cleanup) // 只執行一次資源清理        }    }()    // 異步任務邏輯}

11.使用sync.Map實現并發安全的映射

sync.Map是Go語言標準庫中提供的并發安全的映射類型,可在多個協程之間安全地進行讀寫操作。cYh28資訊網——每日最新資訊28at.com

var m sync.Map// 存儲鍵值對m.Store("key", "value")// 獲取值if val, ok := m.Load("key"); ok {    // 使用值}// 刪除鍵m.Delete("key")

12.使用context.Context進行協程管理和取消

context.Context用于在協程之間傳遞上下文信息,并可用于取消或超時控制。可以使用context.WithCancel()創建一個可取消的上下文,并使用context.WithTimeout()創建一個帶有超時的上下文。cYh28資訊網——每日最新資訊28at.com

ctx, cancel := context.WithCancel(context.Background())go func() {    // 異步任務邏輯    if someCondition {        cancel() // 取消任務    }}()// 等待任務完成或取消select {case <-ctx.Done():    // 任務被取消或超時}

13.使用context.WithDeadline()和context.WithTimeout()設置截止時間

context.WithDeadline()和context.WithTimeout()函數可以用于創建帶有截止時間的上下文,以限制異步任務的執行時間。cYh28資訊網——每日最新資訊28at.com

func doTask(ctx context.Context) {    // 異步任務邏輯    select {    case <-time.After(5 * time.Second):        // 超時處理    case <-ctx.Done():        // 上下文取消處理    }}func main() {    ctx := context.Background()    ctx, cancel := context.WithTimeout(ctx, 3*time.Second)    defer cancel()    go doTask(ctx)    // 繼續其他操作}

14.使用context.WithValue()傳遞上下文值

context.WithValue()函數可用于在上下文中傳遞鍵值對,以在協程之間共享和傳遞上下文相關的值。cYh28資訊網——每日最新資訊28at.com

type keyContextValue stringfunc doTask(ctx context.Context) {    if val := ctx.Value(keyContextValue("key")); val != nil {        // 使用上下文值    }}func main() {    ctx := context.WithValue(context.Background(), keyContextValue("key"), "value")    go doTask(ctx)    // 繼續其他操作}

15.使用atomic包進行原子操作

atomic包提供了一組函數,用于實現原子操作,以確保在并發環境中對共享變量的讀寫操作是原子的。cYh28資訊網——每日最新資訊28at.com

var counter int64func increment() {    atomic.AddInt64(&counter, 1)}func main() {    var wg sync.WaitGroup    for i := 0; i < 100; i++ {        wg.Add(1)        go func() {            defer wg.Done()            increment()        }()    }    wg.Wait()    fmt.Println("Counter:", counter)}

本文鏈接:http://www.www897cc.com/showinfo-26-85231-0.htmlGolang異步編程方式和技巧

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: React 18的并發渲染:顛覆傳統的性能飛躍

下一篇: 討論萬能頭文件&lt;bits/stdc++.h&gt; 在C++中的使用

標簽:
  • 熱門焦點
  • 5月iOS設備性能榜:M1 M2依舊是榜單前五

    和上個月一樣,沒有新品發布的iOS設備性能榜的上榜設備并沒有什么更替,僅僅只有跑分變化而產生的排名變動,剛剛開始的蘋果WWDC2023,推出的產品也依舊是新款Mac Pro、新款Mac Stu
  • 28個SpringBoot項目中常用注解,日常開發、求職面試不再懵圈

    前言在使用SpringBoot開發中或者在求職面試中都會使用到很多注解或者問到注解相關的知識。本文主要對一些常用的注解進行了總結,同時也會舉出具體例子,供大家學習和參考。注解
  • 之家push系統迭代之路

    前言在這個信息爆炸的互聯網時代,能夠及時準確獲取信息是當今社會要解決的關鍵問題之一。隨著之家用戶體量和內容規模的不斷增大,傳統的靠"主動拉"獲取信息的方式已不能滿足用
  • 自動化在DevOps中的力量:簡化軟件開發和交付

    自動化在DevOps中扮演著重要角色,它提升了DevOps的效能。通過自動化工具和方法,DevOps團隊可以實現以下目標:消除手動和重復性任務。簡化流程。在整個軟件開發生命周期中實現更
  • 中國家電海外掘金正當時|出海專題

    作者|吳南南編輯|胡展嘉運營|陳佳慧出品|零態LT(ID:LingTai_LT)2023年,出海市場戰況空前,中國創業者在海外紛紛摩拳擦掌,以期能夠把中國的商業模式、創業理念、戰略打法輸出海外,他們依
  • 品牌洞察丨服務本地,美團直播成效幾何?

    來源:17PR7月11日,美團App首頁推薦位出現&ldquo;美團直播&rdquo;的固定入口。在直播聚合頁面,外賣&ldquo;神槍手&rdquo;直播間、美團旅行直播間、美團買菜直播間等均已上線,同時
  • 7月4日見!iQOO 11S官宣:“雞血版”驍龍8 Gen2+200W快充加持

    上半年已接近尾聲,截至目前各大品牌旗下的頂級旗艦都已悉數亮相,而下半年即將推出的頂級旗艦已經成為了數碼圈爆料的主流,其中就包括全新的iQOO 11S系
  • 英特爾Xe-HP項目終止,將專注Xe-HPC/HPG系列顯卡

    據10 月 31 日消息報道,英特爾高級副總裁兼加速計算系統和圖形事業部總經理 表示,Xe-HP“ Arctic Sound” 系列服務器 GPU 已經應用于 oneAPI devcloud 云服
  • 親歷馬斯克血洗Twitter,硅谷的苦日子在后頭

    文/劉哲銘  編輯/李薇  馬斯克再次揮下裁員大刀。  美國時間11月14日,Twitter約4400名外包員工遭解雇,此次被解雇的員工的主要工作為內容審核等。此前,T
Top 主站蜘蛛池模板: 通州市| 芒康县| 施秉县| 黎城县| 德兴市| 琼结县| 台南市| 泰州市| 达州市| 铜陵市| 巫山县| 黄陵县| 安吉县| 宁津县| 贺兰县| 寿光市| 江孜县| 和龙市| 剑河县| 喀喇沁旗| 如东县| 田林县| 筠连县| 连州市| 神木县| 定安县| 肥东县| 长海县| 敦煌市| 疏勒县| 藁城市| 永定县| 平顺县| 麻阳| 顺昌县| 克拉玛依市| 清远市| 陈巴尔虎旗| 宜川县| 铁岭市| 云龙县|