佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > Go 并發(fā)實現(xiàn)協(xié)程同步的多種解決方法

Go 并發(fā)實現(xiàn)協(xié)程同步的多種解決方法

熱門標簽:網(wǎng)站排名優(yōu)化 服務外包 呼叫中心市場需求 Linux服務器 AI電銷 百度競價排名 鐵路電話系統(tǒng) 地方門戶網(wǎng)站

go 簡潔的并發(fā)

多核處理器越來越普及。有沒有一種簡單的辦法,能夠讓我們寫的軟件釋放多核的威力?是有的。隨著Golang, Erlang, Scala等為并發(fā)設計的程序語言的興起,新的并發(fā)模式逐漸清晰。正如過程式編程和面向對象一樣,一個好的編程模式有一個極其簡潔的內核,還有在此之上豐富的外延。可以解決現(xiàn)實世界中各種各樣的問題。本文以GO語言為例,解釋其中內核、外延。

前言

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

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

執(zhí)行以上代碼很可能看不到輸出。

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

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

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

Sleep 一段時間

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

 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秒,等待上面兩個協(xié)程結束
}

這兩個簡單的協(xié)程執(zhí)行消耗的時間很短的,所以你會發(fā)現(xiàn)現(xiàn)在就有結果出現(xiàn)了。

Goroutine 1
Goroutine 2

為什么上面我要說 “可能會出現(xiàn)” ?

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

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

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

管道實現(xiàn)同步

那么用管道怎么實現(xiàn)同步呢?show code:

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

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

sync.WaitGroup

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

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

  • Add() 用來添加計數(shù)
  • Done() 用來在操作結束時調用,使計數(shù)減一
  • Wait() 用來等待所有的操作結束,即計數(shù)變?yōu)?0,該函數(shù)會在計數(shù)不為 0 時等待,在計數(shù)為 0 時立即返回

繼續(xù) show code:

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

你會發(fā)現(xiàn)也是可以看到運行結果的,是不是發(fā)現(xiàn)這種方式是很簡單的。

總結

以上所述是小編給大家介紹的Go 并發(fā)實現(xiàn)協(xié)程同步的多種解決方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

您可能感興趣的文章:
  • go等待一組協(xié)程結束的操作方式
  • golang協(xié)程池模擬實現(xiàn)群發(fā)郵件功能
  • 解決go在函數(shù)退出后子協(xié)程的退出問題
  • Go使用協(xié)程交替打印字符
  • Golang 之協(xié)程的用法講解
  • go 協(xié)程返回值處理操作
  • 淺談golang for 循環(huán)中使用協(xié)程的問題
  • Go并發(fā):使用sync.WaitGroup實現(xiàn)協(xié)程同步方式

標簽:湘潭 湖南 仙桃 黃山 銅川 崇左 蘭州 衡水

巨人網(wǎng)絡通訊聲明:本文標題《Go 并發(fā)實現(xiàn)協(xié)程同步的多種解決方法》,本文關鍵詞  ;如發(fā)現(xiàn)本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。
  • 相關文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    筠连县| 伊金霍洛旗| 青海省| 陵川县| 抚宁县| 石嘴山市| 湟中县| 普安县| 云霄县| 峨边| 云安县| 泸西县| 江西省| 乌鲁木齐市| 丹凤县| 泽州县| 汤阴县| 眉山市| 贵阳市| 浪卡子县| 兴山县| 二手房| 临西县| 依安县| 江西省| 安远县| 石城县| 金坛市| 九寨沟县| 托里县| 南澳县| 赣州市| 福安市| 美姑县| 张家口市| 扶余县| 东辽县| 来安县| 垫江县| 桂阳县| 紫阳县|