自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

sync.WaitGroup和sync.Once的愛恨情仇

開發(fā) 前端
通過本文,我們了解了Go語言中的兩個(gè)重要同步工具:?sync.WaitGroup? 和 ?sync.Once?。?sync.WaitGroup? 用于等待一組 goroutine 完成,而 ?sync.Once? 則確保某些操作只執(zhí)行一次。

今天,我們將繼續(xù)探討Go語言中的兩個(gè)重要的同步工具:sync.WaitGroup 和 sync.Once。

sync.WaitGroup

sync.WaitGroup 是Go語言中的一種計(jì)數(shù)信號(hào)量,用于等待一組 goroutine 完成。它常用于等待一組并發(fā)任務(wù)全部完成后再繼續(xù)執(zhí)行。

使用方法

  1. 聲明一個(gè) sync.WaitGroup 類型的變量。
  2. 在每個(gè) goroutine 啟動(dòng)之前調(diào)用 Add 方法,增加等待計(jì)數(shù)。
  3. 在每個(gè) goroutine 完成時(shí)調(diào)用 Done 方法,減少等待計(jì)數(shù)。
  4. 在主 goroutine 中調(diào)用 Wait 方法,阻塞直到所有 goroutine 完成。

示例代碼

package main

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

func worker(id int, wg *sync.WaitGroup) {
   defer wg.Done()
   fmt.Printf("Worker %d starting\n", id)
   time.Sleep(time.Second)
   fmt.Printf("Worker %d done\n", id)
}

func main() {
   var wg sync.WaitGroup

   for i := 1; i <= 5; i++ {
       wg.Add(1)
       go worker(i, &wg)
  }

   wg.Wait()
   fmt.Println("All workers done")
}

在這個(gè)例子中,main 函數(shù)啟動(dòng)了5個(gè) goroutine,每個(gè) goroutine 都會(huì)運(yùn)行 worker 函數(shù)。每個(gè) worker 在完成時(shí)調(diào)用 wg.Done(),而 main 函數(shù)會(huì)等待所有 worker 完成后再繼續(xù)執(zhí)行。

注意事項(xiàng)

  • WaitGroup 的計(jì)數(shù)器不能設(shè)為負(fù)數(shù),否則會(huì)引發(fā) panic。
  • 必須確保在所有 Done 調(diào)用之前已經(jīng)調(diào)用了 Add。

sync.Once

sync.Once 是一個(gè)用于確保某些操作只執(zhí)行一次的結(jié)構(gòu)體。它提供了一種線程安全的方式來執(zhí)行一次性初始化操作。

使用方法

  1. 聲明一個(gè) sync.Once 類型的變量。
  2. 使用 Do 方法執(zhí)行需要僅執(zhí)行一次的操作。

示例代碼

package main

import (
   "fmt"
   "sync"
)

func initialize() {
   fmt.Println("Initializing...")
}

func main() {
   var once sync.Once

   for i := 0; i < 10; i++ {
       go func(i int) {
           once.Do(initialize)
           fmt.Printf("Goroutine %d\n", i)
      }(i)
  }

   // 等待所有 goroutine 完成
   var wg sync.WaitGroup
   wg.Add(10)
   for i := 0; i < 10; i++ {
       go func() {
           defer wg.Done()
           once.Do(initialize)
      }()
  }
   wg.Wait()
}

在這個(gè)例子中,initialize 函數(shù)只會(huì)被執(zhí)行一次,盡管有多個(gè) goroutine 嘗試調(diào)用 once.Do(initialize)。

注意事項(xiàng)

  • sync.Once 的 Do 方法接受一個(gè)無參函數(shù)。
  • 即使 Do 方法被多次調(diào)用,傳入的函數(shù)也只會(huì)執(zhí)行一次。

結(jié)合使用示例

我們可以結(jié)合 sync.WaitGroup 和 sync.Once,來完成一個(gè)更復(fù)雜的并發(fā)任務(wù)。假設(shè)我們有一個(gè)初始化操作,只需執(zhí)行一次,但在多個(gè) goroutine 中執(zhí)行其他任務(wù)。

示例代碼

package main

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

var (
   once sync.Once
   wg   sync.WaitGroup
)

func initialize() {
   fmt.Println("Initializing...")
   time.Sleep(2 * time.Second) // 模擬初始化耗時(shí)
   fmt.Println("Initialization complete")
}

func worker(id int) {
   defer wg.Done()
   once.Do(initialize)
   fmt.Printf("Worker %d starting\n", id)
   time.Sleep(time.Second) // 模擬工作
   fmt.Printf("Worker %d done\n", id)
}

func main() {
   const numWorkers = 5
   wg.Add(numWorkers)

   for i := 1; i <= numWorkers; i++ {
       go worker(i)
  }

   wg.Wait()
   fmt.Println("All workers done")
}

在這個(gè)例子中,initialize 函數(shù)只會(huì)執(zhí)行一次,而 worker 函數(shù)會(huì)并發(fā)執(zhí)行,等待所有 worker 完成后,程序才會(huì)繼續(xù)執(zhí)行。

總結(jié)

通過本文,我們了解了Go語言中的兩個(gè)重要同步工具:sync.WaitGroup 和 sync.Once。sync.WaitGroup 用于等待一組 goroutine 完成,而 sync.Once 則確保某些操作只執(zhí)行一次。這兩個(gè)工具在實(shí)際開發(fā)中非常實(shí)用,能有效地幫助我們處理并發(fā)任務(wù)。

責(zé)任編輯:武曉燕 來源: 架構(gòu)師秋天
相關(guān)推薦

2024-01-08 13:40:00

并發(fā)安全? 數(shù)量

2021-08-29 18:13:03

緩存失效數(shù)據(jù)

2023-10-20 13:35:19

GoWaitGroup

2023-06-05 09:23:00

Golang同步工具

2023-06-06 08:28:58

Sync.OnceGolang

2023-03-28 08:20:07

場(chǎng)景sync.Once?系統(tǒng)

2025-01-03 09:39:04

2022-09-02 12:13:22

TCPUDP場(chǎng)景

2022-05-13 09:47:28

Docker容器

2021-04-12 06:08:16

HiveSpark大數(shù)據(jù)

2019-05-15 15:10:12

Tomcat Session Cookie

2020-11-24 10:13:20

測(cè)試開發(fā)管理

2024-08-07 08:22:27

2022-06-07 08:55:04

Golang單例模式語言

2025-03-24 00:25:00

Go語言并發(fā)編程

2025-04-03 09:12:26

GolangWaitGroup工具

2024-06-07 00:09:50

2011-08-15 14:06:28

sync中文man

2025-01-13 00:00:35

2020-04-09 15:26:55

間諜軟件NSOFacebook
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)