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

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

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

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

package main

import "fmt"

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

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

在這里插入圖片描述

deadlock表示我們程序中的 goroutine 都被掛起導致程序死鎖了。為什么會出現(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()
}

在這里插入圖片描述

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

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

當我們將讀的協(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ā)送值的操作那么也會導致接收操作阻塞

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()
}

在這里插入圖片描述

同理,因為當程序執(zhí)行到 v := <-ch 時,進已經發(fā)生了阻塞,下面的go協(xié)程還沒有來得及啟動。
當我們將寫的協(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()
}

在這里插入圖片描述

使用無緩沖通道進行通信將導致發(fā)送和接收的 goroutine 同步化。因此,無緩沖通道也被稱為同步通道。
同步:兩個goroutine1(寫入方)、goroutine2(讀取方),
goroutine1先執(zhí)行,如果想要再次發(fā)送(寫入)數(shù)據的話,必須等待goroutine2將channel中的數(shù)據取出來(讀取)之后,才能再次發(fā)送。
goroutine2先執(zhí)行,如果想要再次接收數(shù)據的話,必須等待goroutine1再次向channel中寫入數(shù)據之后,才能再次接收。
執(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
    }

}

在這里插入圖片描述

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

相關文章

  • B站新一代 golang規(guī)則引擎gengine基礎語法

    B站新一代 golang規(guī)則引擎gengine基礎語法

    這篇文章主要為大家介紹了B站新一代 golang規(guī)則引擎gengine基礎語法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Golang中Gin數(shù)據庫表名前綴的三種方法

    Golang中Gin數(shù)據庫表名前綴的三種方法

    本文主要介紹了Golang中Gin數(shù)據庫表名前綴的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-02-02
  • 揭秘Go語言中的反射機制

    揭秘Go語言中的反射機制

    在Go語言中,反射是通過reflect包來實現(xiàn)的,通過使用反射,我們可以在運行時獲取對象的類型信息、訪問對象的字段和方法、動態(tài)調用方法等,反射在很多場景下都非常有用,比如編寫通用的代碼、實現(xiàn)對象的序列化和反序列化、實現(xiàn)依賴注入等,需要的朋友可以參考下
    2023-10-10
  • golang中的并發(fā)和并行

    golang中的并發(fā)和并行

    這篇文章主要介紹了golang中的并發(fā)和并行用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 一文徹底理解Golang閉包實現(xiàn)原理

    一文徹底理解Golang閉包實現(xiàn)原理

    閉包對于一個長期寫Java的開發(fā)者來說估計鮮有耳聞,光這名字感覺就有點"神秘莫測"。這篇文章的主要目的就是從編譯器的角度來分析閉包,徹底搞懂閉包的實現(xiàn)原理,需要的可以參考一下
    2022-10-10
  • Golang標準庫time包日常用法小結

    Golang標準庫time包日常用法小結

    本文主要介紹了Golang標準庫time包日常用法小結,可以通過它們來獲取當前時間、創(chuàng)建指定時間、解析時間字符串、控制時間間隔等操作,感興趣的可以了解一下
    2023-11-11
  • 談談golang的netpoll原理解析

    談談golang的netpoll原理解析

    本文詳細介紹了Go語言中netpoll部分的實現(xiàn)細節(jié)和協(xié)程阻塞調度原理,特別是epoll在Linux環(huán)境下的工作原理,Go語言通過將epoll操作放在runtime包中,結合運行時調度功能,實現(xiàn)了高效的協(xié)程I/O操作,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • 利用Go語言搭建WebSocket服務端方法示例

    利用Go語言搭建WebSocket服務端方法示例

    這篇文章主要給大家介紹了利用Go語言搭建WebSocket服務端方法,文中通過示例代碼介紹的非常詳細,需要的朋友們可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • 使用Go調用第三方API的方法詳解

    使用Go調用第三方API的方法詳解

    在現(xiàn)代應用開發(fā)中,調用第三方API是非常常見的場景,比如獲取天氣預報、翻譯文本、發(fā)送短信等,Go作為一門高效并發(fā)的編程語言,擁有強大的標準庫和豐富的第三方庫,可以非常方便地與外部API進行交互,本文將通過兩個實戰(zhàn)案例,帶你掌握如何在Go中調用第三方 API
    2025-09-09
  • golang切片反序實例

    golang切片反序實例

    這篇文章主要介紹了golang切片反序實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評論