欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2018年08月31日 09:46:11   投稿:mrr  
這篇文章主要介紹了Go 并發(fā)——實(shí)現(xiàn)協(xié)程同步的多種解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

go 簡(jiǎn)潔的并發(fā)

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

前言

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

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

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

因?yàn)橛锌赡苓@兩個(gè)協(xié)程還沒(méi)得到執(zhí)行,主協(xié)程就已經(jīng)結(jié)束了,而主協(xié)程結(jié)束時(shí)會(huì)結(jié)束所有其他協(xié)程,所以導(dǎo)致代碼運(yùn)行的結(jié)果什么都沒(méi)有。

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

下面說(shuō)幾種可以解決的方法:

Sleep 一段時(shí)間

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

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

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

Goroutine 1
Goroutine 2

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

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

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

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

管道實(shí)現(xiàn)同步

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

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

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

sync.WaitGroup

其實(shí) go 里面也提供了更簡(jiǎn)單的方式 —— 使用 sync.WaitGroup。

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

  • Add() 用來(lái)添加計(jì)數(shù)
  • Done() 用來(lái)在操作結(jié)束時(shí)調(diào)用,使計(jì)數(shù)減一
  • Wait() 用來(lái)等待所有的操作結(jié)束,即計(jì)數(shù)變?yōu)?0,該函數(shù)會(huì)在計(jì)數(shù)不為 0 時(shí)等待,在計(jì)數(shù)為 0 時(shí)立即返回

繼續(xù) show code:

package main
 import (
   "fmt"
  "sync"
 )
 func main() {
  var wg sync.WaitGroup
  wg.Add(2) // 因?yàn)橛袃蓚€(gè)動(dòng)作,所以增加2個(gè)計(jì)數(shù)
  go func() {
    fmt.Println("Goroutine 1")
    wg.Done() // 操作完成,減少一個(gè)計(jì)數(shù)
  }()
  go func() {
    fmt.Println("Goroutine 2")
    wg.Done() // 操作完成,減少一個(gè)計(jì)數(shù)
  }()
  wg.Wait() // 等待,直到計(jì)數(shù)為0
}

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

總結(jié)

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

相關(guān)文章

  • 淺析Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制

    淺析Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制

    這篇文章主要為大家詳細(xì)介紹了Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-10-10
  • Golang中的Unicode與字符串示例詳解

    Golang中的Unicode與字符串示例詳解

    這篇文章主要給大家介紹了關(guān)于Golang中Unicode與字符串的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Golang具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • golang中的時(shí)間格式化

    golang中的時(shí)間格式化

    這篇文章主要介紹了golang中的時(shí)間格式化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • golang微服務(wù)框架kratos實(shí)現(xiàn)Socket.IO服務(wù)的方法

    golang微服務(wù)框架kratos實(shí)現(xiàn)Socket.IO服務(wù)的方法

    本文主要介紹了golang微服務(wù)框架kratos實(shí)現(xiàn)Socket.IO服務(wù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 深入理解Go gin框架中Context的Request和Writer對(duì)象

    深入理解Go gin框架中Context的Request和Writer對(duì)象

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言的gin框架中Context的Request和Writer對(duì)象,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Go語(yǔ)言有一定的幫助,快跟隨小編一起學(xué)習(xí)一下吧
    2023-04-04
  • 基于Go語(yǔ)言實(shí)現(xiàn)冒泡排序算法

    基于Go語(yǔ)言實(shí)現(xiàn)冒泡排序算法

    冒泡排序是交換排序中最簡(jiǎn)單的一種算法。這篇文章將利用Go語(yǔ)言實(shí)現(xiàn)冒泡排序算法,文中的示例代碼講解詳細(xì),對(duì)學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考一下
    2022-12-12
  • golang獲取變量或?qū)ο箢?lèi)型的幾種方式總結(jié)

    golang獲取變量或?qū)ο箢?lèi)型的幾種方式總結(jié)

    在golang中并沒(méi)有提供內(nèi)置函數(shù)來(lái)獲取變量的類(lèi)型,但是通過(guò)一定的方式也可以獲取,下面這篇文章主要給大家介紹了關(guān)于golang獲取變量或?qū)ο箢?lèi)型的幾種方式,需要的朋友可以參考下
    2022-12-12
  • Go分布式鏈路追蹤實(shí)戰(zhàn)探索

    Go分布式鏈路追蹤實(shí)戰(zhàn)探索

    這篇文章主要為大家介紹了Go分布式鏈路追蹤實(shí)戰(zhàn)示例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go語(yǔ)言使用Timeout Context取消任務(wù)的實(shí)現(xiàn)

    Go語(yǔ)言使用Timeout Context取消任務(wù)的實(shí)現(xiàn)

    本文主要介紹了Go語(yǔ)言使用Timeout Context取消任務(wù)的實(shí)現(xiàn),包括基本的任務(wù)取消和控制HTTP客戶(hù)端請(qǐng)求的超時(shí),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • golang中sync.Mutex的實(shí)現(xiàn)方法

    golang中sync.Mutex的實(shí)現(xiàn)方法

    本文主要介紹了golang中sync.Mutex的實(shí)現(xiàn)方法,mutex?主要有兩個(gè)?method:?Lock()?和?Unlock(),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04

最新評(píng)論