日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Go語言通過WaitGroup實現控制并發的示例詳解_Golang

作者:孫琦Ray ? 更新時間: 2023-03-26 編程語言

與Channel區別

Channel能夠很好的幫助我們控制并發,但是在開發習慣上與顯示的表達不太相同,所以在Go語言中可以利用sync包中的WaitGroup實現并發控制,更加直觀。

基本使用示例

我們將之前的示例加以改造,引入sync.WaitGroup來實現并發控制。

首先我們在主函數中定義WaitGroup

var wg sync.WaitGroup

每執行一個任務,則調用Add()方法

wg.Add(1)

在主函數中我們利用Wait()方法等待并發結束

wg.Wait()

在調用的函數中,我們需要將WaitGroup以指針方式傳入,否則將造成Deadlock

// 主函數內
go ready(5, &wg)

// 函數
func ready(s int, wg *sync.WaitGroup)

同時在函數執行完成后,調用wg.Done,我們使用defer實現

defer wg.Done()

完整代碼

package main

import (
    "fmt"
    "sync"
    "time"
)

func ready(s int, wg *sync.WaitGroup) {

    defer wg.Done()

    fmt.Printf("Run func in a goroutine and wait for %v\n", s)
    time.Sleep(time.Second * time.Duration(s))
    fmt.Printf("Run func in a goroutine and wait for %v end\n", s)
}

func main() {

    var wg sync.WaitGroup

    wg.Add(1)
    go ready(5, &wg)

    mainWaitSec := 2
    fmt.Printf("Run Main function and wait for %v\n", mainWaitSec)
    time.Sleep(time.Second * time.Duration(mainWaitSec))
    fmt.Printf("Run Main function and wait for %v done\n", mainWaitSec)

    wg.Wait()

}

特別提示

WaitGroup傳入給函數時,需要以指針方式傳遞,否則會造成Deadlock

多任務示例

如果不想在函數中傳遞WaitGroup,也可以采用以下這種方式,通過并發匿名函數的方式,在主函數邏輯中對并發進行精準控制

    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)

        waitSec := i + 1
        go func() {
            defer wg.Done()
            ready(waitSec)
        }()
    }

完整代碼

package main

import (
    "fmt"
    "sync"
    "time"
)

func ready(s int) {
    fmt.Printf("Run func in a goroutine and wait for %v\n", s)
    time.Sleep(time.Second * time.Duration(s))
    fmt.Printf("Run func in a goroutine and wait for %v end\n", s)
}

func main() {

    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)

        waitSec := i + 1
        go func() {
            defer wg.Done()
            ready(waitSec)
        }()
    }

    mainWaitSec := 2
    fmt.Printf("Run Main function and wait for %v\n", mainWaitSec)
    time.Sleep(time.Second * time.Duration(mainWaitSec))
    fmt.Printf("Run Main function and wait for %v done\n", mainWaitSec)

    wg.Wait()

}

運行結果如下

Run Main function and wait for 2
Run func in a goroutine and wait for 2
Run func in a goroutine and wait for 4
Run func in a goroutine and wait for 5
Run func in a goroutine and wait for 1
Run func in a goroutine and wait for 3
Run func in a goroutine and wait for 1 end
Run Main function and wait for 2 done
Run func in a goroutine and wait for 2 end
Run func in a goroutine and wait for 3 end
Run func in a goroutine and wait for 4 end
Run func in a goroutine and wait for 5 end

原文鏈接:https://blog.csdn.net/xiaoquqi/article/details/128768025

欄目分類
最近更新