最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go無緩沖通道(同步通道)的實現(xiàn)

 更新時間:2025年02月06日 09:53:07   作者:2301_76723322  
本文主要介紹了Go無緩沖通道(同步通道)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

無緩沖的通道又稱為阻塞的通道,我們來看一下如下代碼片段。

package main

import "fmt"

func main() {
    ch := make(chan int)
    ch <- 1
    fmt.Println("發(fā)送成功")
}

上面這段代碼能夠通過編譯,但是執(zhí)行的時候會出現(xiàn)以下錯誤:

在這里插入圖片描述

deadlock表示我們程序中的 goroutine 都被掛起導(dǎo)致程序死鎖了。為什么會出現(xiàn)deadlock錯誤呢?

因為我們使用ch := make(chan int)創(chuàng)建的是無緩沖的通道,無緩沖的通道只有在有接收方能夠接收值的時候才能發(fā)送成功,否則會一直處于等待發(fā)送的階段。

上面的代碼會阻塞在ch <- 1這一行代碼形成死鎖,那如何解決這個問題呢?

其中一種可行的方法是創(chuàng)建一個 goroutine 去接收值,例如:

package main

import (
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    ch := make(chan int)
    ch <- 1
    go func() {
       defer wg.Done()
        v := <-ch
       fmt.Println(v)
    }()
    close(ch)
    wg.Wait()
}

在這里插入圖片描述

我們已經(jīng)開了一個go協(xié)程從管道中讀去數(shù)據(jù)了,為什么還會報錯呢?

因為當(dāng)程序執(zhí)行到 ch <- 1時,進已經(jīng)發(fā)生了阻塞,下面的go協(xié)程還沒有來得及啟動。
go的channel在執(zhí)行寫入時會先檢查在此之前有沒有讀取數(shù)據(jù)的一方已經(jīng)存在,在讀取時會先檢查在此之前有沒有寫入方已經(jīng)存在。

當(dāng)我們將讀的協(xié)程先啟動,再寫入,就可以了,代碼如下:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    ch := make(chan int)
    go func() {
       defer wg.Done()
       v := <-ch
       fmt.Println(v)
    }()
    ch <- 1
    close(ch)
    wg.Wait()
}

在這里插入圖片描述

同理,如果對一個無緩沖通道執(zhí)行接收操作時,沒有任何向通道中發(fā)送值的操作那么也會導(dǎo)致接收操作阻塞。

package main

import "fmt"

func main() {
    ch := make(chan int)
    <-ch
    fmt.Println("接收成功")
}

在這里插入圖片描述

其中一種可行的方法是創(chuàng)建一個 goroutine 去寫入值,例如:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    ch := make(chan int)
    v := <-ch
    go func() {
       defer wg.Done()
       ch <- 1
    }()
    fmt.Println(v)
    close(ch)
    wg.Wait()
}

在這里插入圖片描述

同理,因為當(dāng)程序執(zhí)行到 v := <-ch 時,進已經(jīng)發(fā)生了阻塞,下面的go協(xié)程還沒有來得及啟動。
當(dāng)我們將寫的協(xié)程先啟動,再讀取,就可以了,代碼如下:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    ch := make(chan int)
    go func() {
       defer wg.Done()
       ch <- 1
    }()
    v := <-ch
    fmt.Println(v)
    close(ch)
    wg.Wait()
}

在這里插入圖片描述

使用無緩沖通道進行通信將導(dǎo)致發(fā)送和接收的 goroutine 同步化。因此,無緩沖通道也被稱為同步通道。
同步:兩個goroutine1(寫入方)、goroutine2(讀取方),
goroutine1先執(zhí)行,如果想要再次發(fā)送(寫入)數(shù)據(jù)的話,必須等待goroutine2將channel中的數(shù)據(jù)取出來(讀取)之后,才能再次發(fā)送。
goroutine2先執(zhí)行,如果想要再次接收數(shù)據(jù)的話,必須等待goroutine1再次向channel中寫入數(shù)據(jù)之后,才能再次接收。
執(zhí)行順序(goroutine1,goroutine2,goroutine1,goroutine2…)goroutine1和goroutine2交替執(zhí)行。
示例演示:使用一個無緩沖channel和兩個goroutine實現(xiàn)交替打印一個字符串。

package main

import "fmt"

func main() {
    ch := make(chan int)

    str := "hello, world"

    go func() {
       for {
          index, ok := <-ch
          if !ok {
             break
          }
          if index >= len(str) {
             close(ch)
             break
          }
          fmt.Printf("Goroutine1 : %c\n", str[index])
          ch <- index + 1
       }
    }()

    ch <- 0

    for {
       index, ok := <-ch
       if !ok {
          break
       }
       if index >= len(str) {
          close(ch)
          break
       }
       fmt.Printf("Goroutine1 : %c\n", str[index])
       ch <- index + 1
    }

}

在這里插入圖片描述

到此這篇關(guān)于Go無緩沖通道(同步通道)的實現(xiàn)的文章就介紹到這了,更多相關(guān)Go無緩沖通道內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • golang原生http包實現(xiàn)各種情況的get請求方式

    golang原生http包實現(xiàn)各種情況的get請求方式

    這篇文章主要介紹了golang原生http包實現(xiàn)各種情況的get請求方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Go中unsafe.Pointer類型的使用小結(jié)

    Go中unsafe.Pointer類型的使用小結(jié)

    unsafe.Pointer?是?Go?語言標(biāo)準(zhǔn)庫?unsafe?包中的一個特殊類型,用于在不同類型的指針之間進行?無類型轉(zhuǎn)換,允許你繞過?Go?的類型系統(tǒng)進行底層操作,感興趣的可以了解一下
    2026-02-02
  • Go語言變量與基礎(chǔ)數(shù)據(jù)類型詳情

    Go語言變量與基礎(chǔ)數(shù)據(jù)類型詳情

    Go 是靜態(tài)(編譯型)語言,是區(qū)別于解釋型語言的弱類型語言(靜態(tài):類型固定,強類型:不同類型不允許直接運算),下面文章將對其進行詳細介紹,需要的朋友可以參考一下
    2021-09-09
  • 如何使用go-zero開發(fā)線上項目

    如何使用go-zero開發(fā)線上項目

    這篇文章主要介紹了如何使用go-zero開發(fā)線上項目,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Go語言中的多種測試方法

    Go語言中的多種測試方法

    本文主要介紹了Go語言中的多種測試方法,包括單元測試、表格驅(qū)動測試、基準(zhǔn)測試等,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • Golang設(shè)計模式之責(zé)任鏈模式講解和代碼示例

    Golang設(shè)計模式之責(zé)任鏈模式講解和代碼示例

    責(zé)任鏈?zhǔn)且环N行為設(shè)計模式, 允許你將請求沿著處理者鏈進行發(fā)送, 直至其中一個處理者對其進行處理,本文就詳細給大家介紹一下Golang 責(zé)任鏈模式,文中有詳細的代碼示例,需要的朋友可以參考下
    2023-06-06
  • 使用go xorm來操作mysql的方法實例

    使用go xorm來操作mysql的方法實例

    今天小編就為大家分享一篇關(guān)于使用go xorm來操作mysql的方法實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • 一文帶你揭秘Go中new()和make()函數(shù)的區(qū)別和用途

    一文帶你揭秘Go中new()和make()函數(shù)的區(qū)別和用途

    Go(或 Golang)是一種現(xiàn)代、靜態(tài)類型、編譯型的編程語言,專為構(gòu)建可擴展、并發(fā)和高效的軟件而設(shè)計,它提供了各種內(nèi)置的函數(shù)和特性,幫助開發(fā)人員編寫簡潔高效的代碼,在本博客文章中,我們將探討 new() 和 make() 函數(shù)之間的區(qū)別,了解何時以及如何有效地使用它們
    2023-10-10
  • Go語言中的goroutine和channel如何協(xié)同工作

    Go語言中的goroutine和channel如何協(xié)同工作

    在Go語言中,goroutine和channel是并發(fā)編程的兩個核心概念,它們協(xié)同工作以實現(xiàn)高效、安全的并發(fā)執(zhí)行,本文將詳細探討goroutine和channel如何協(xié)同工作,以及它們在并發(fā)編程中的作用和優(yōu)勢,需要的朋友可以參考下
    2024-04-04
  • golang壓縮與解壓縮文件的示例代碼

    golang壓縮與解壓縮文件的示例代碼

    這篇文章主要給大家介紹了golang壓縮與解壓縮文件,文中通過代碼示例給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02

最新評論

吴堡县| 玉屏| 浦县| 肥城市| 抚顺县| 孝昌县| 札达县| 健康| 隆化县| 台州市| 汪清县| 余江县| 珲春市| 南通市| 宝清县| 灌云县| 疏附县| 蒙山县| 南安市| 哈尔滨市| 米脂县| 盐源县| 景德镇市| 荥经县| 永胜县| 三门峡市| 乐清市| 策勒县| 公安县| 砀山县| 浮山县| 天全县| 通化县| 宜川县| 宁德市| 榆社县| 福贡县| 溆浦县| 湘西| 龙南县| 龙里县|