91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在golang中利用并發實現協程同步

發布時間:2021-05-21 16:38:58 來源:億速云 閱讀:277 作者:Leah 欄目:編程語言

怎么在golang中利用并發實現協程同步?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Java 中有一系列的線程同步的方法,go 里面有 goroutine(協程),先看下下面的代碼執行的結果是什么呢?

 package main
 import (
   "fmt"
)
 func main() {
  go func() {
    fmt.Println("Goroutine 1")
  }()
  go func() {
    fmt.Println("Goroutine 2")
  }()
}

執行以上代碼很可能看不到輸出。

因為有可能這兩個協程還沒得到執行,主協程就已經結束了,而主協程結束時會結束所有其他協程,所以導致代碼運行的結果什么都沒有。

估計不少新接觸 go 的童鞋都會對此郁悶?,可能會問那么該如何等待主協程中創建的協程執行完畢之后再結束主協程呢?

下面說幾種可以解決的方法:

Sleep 一段時間

在 main 方法退出之前 sleep 一段時間就可能會出現結果了,如下代碼:

 package main
 import (
   "fmt"
  "time"
 )
 func main() {
   go func() {
    fmt.Println("Goroutine 1")
  }()
  go func() {
    fmt.Println("Goroutine 2")
  }()
  time.Sleep(time.Second * 1) // 睡眠1秒,等待上面兩個協程結束
}

這兩個簡單的協程執行消耗的時間很短的,所以你會發現現在就有結果出現了。

Goroutine 1
Goroutine 2

為什么上面我要說 “可能會出現” ?

因為 sleep 這個時間目前是設置的 1s,如果我這兩個協程里面執行了很復雜的邏輯操作(時間大于 1s),那么就會發現依舊也是無結果打印出來的。

那么就可以發現這種方式得到問題所在了:我們無法確定需要睡眠多久

上面那種方式有問題,go 里面其實也可以用管道來實現同步的。

管道實現同步

那么用管道怎么實現同步呢?show code:

 package main
 import (
   "fmt"
 )
 func main() {
   ch := make(chan struct{})
  count := 2 // count 表示活動的協程個數
  go func() {
    fmt.Println("Goroutine 1")
    ch <- struct{}{} // 協程結束,發出信號
  }()
  go func() {
    fmt.Println("Goroutine 2")
    ch <- struct{}{} // 協程結束,發出信號
  }()
  for range ch {
    // 每次從ch中接收數據,表明一個活動的協程結束
    count--
    // 當所有活動的協程都結束時,關閉管道
    if count == 0 {
      close(ch)
    }
  }
}

這種方式是一種比較完美的解決方案, goroutine / channel 它們也是在 go 里面經常搭配在一起的一對。

sync.WaitGroup

其實 go 里面也提供了更簡單的方式 —— 使用 sync.WaitGroup。

WaitGroup 顧名思義,就是用來等待一組操作完成的。WaitGroup 內部實現了一個計數器,用來記錄未完成的操作個數,它提供了三個方法:

  • Add() 用來添加計數

  • Done() 用來在操作結束時調用,使計數減一

  • Wait() 用來等待所有的操作結束,即計數變為 0,該函數會在計數不為 0 時等待,在計數為 0 時立即返回

繼續 show code:

package main
 import (
   "fmt"
  "sync"
 )
 func main() {
  var wg sync.WaitGroup
  wg.Add(2) // 因為有兩個動作,所以增加2個計數
  go func() {
    fmt.Println("Goroutine 1")
    wg.Done() // 操作完成,減少一個計數
  }()
  go func() {
    fmt.Println("Goroutine 2")
    wg.Done() // 操作完成,減少一個計數
  }()
  wg.Wait() // 等待,直到計數為0
}

golang適合做什么

golang可以做服務器端開發,但golang很適合做日志處理、數據打包、虛擬機處理、數據庫代理等工作。在網絡編程方面,它還廣泛應用于web應用、API應用等領域。

關于怎么在golang中利用并發實現協程同步問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

东平县| 舒兰市| 南投县| 乃东县| 永仁县| 囊谦县| 若羌县| 久治县| 永胜县| 邢台市| 抚州市| 峨眉山市| 绥芬河市| 田东县| 志丹县| 太原市| 临清市| 芦山县| 酒泉市| 永年县| 河西区| 阿荣旗| 额济纳旗| 安图县| 台东市| 八宿县| 冕宁县| 广西| 甘肃省| 金溪县| 浦江县| 忻州市| 灵寿县| 内丘县| 南川市| 萝北县| 江阴市| 托克托县| 仁化县| 贵定县| 通许县|