日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

深入Go原理:協(xié)程間通信基礎(chǔ)Chan

來源: 責(zé)編: 時(shí)間:2024-05-29 08:53:54 138觀看
導(dǎo)讀在 Go 語言中,chan(通道)是用于在不同 goroutine 之間進(jìn)行通信和同步的重要機(jī)制。它的設(shè)計(jì)和實(shí)現(xiàn)允許在并發(fā)編程中安全、有效地傳遞數(shù)據(jù)。以下是 chan 的工作原理和實(shí)現(xiàn)細(xì)節(jié)基本概念通道類型通道有類型,指定了通道能夠傳

在 Go 語言中,chan(通道)是用于在不同 goroutine 之間進(jìn)行通信和同步的重要機(jī)制。它的設(shè)計(jì)和實(shí)現(xiàn)允許在并發(fā)編程中安全、有效地傳遞數(shù)據(jù)。以下是 chan 的工作原理和實(shí)現(xiàn)細(xì)節(jié)UU128資訊網(wǎng)——每日最新資訊28at.com

基本概念

通道類型

通道有類型,指定了通道能夠傳遞的數(shù)據(jù)類型。例如,chan int 是一個(gè)只能傳遞整數(shù)的通道。UU128資訊網(wǎng)——每日最新資訊28at.com

無緩沖通道

沒有緩沖區(qū)的通道,發(fā)送和接收操作是同步的,即發(fā)送操作會(huì)阻塞直到有接收操作發(fā)生。UU128資訊網(wǎng)——每日最新資訊28at.com

有緩沖通道

具有一定緩沖區(qū)的通道,發(fā)送操作在緩沖區(qū)未滿時(shí)不會(huì)阻塞,直到緩沖區(qū)滿時(shí)才會(huì)阻塞。UU128資訊網(wǎng)——每日最新資訊28at.com

通道的內(nèi)部結(jié)構(gòu)

通道在內(nèi)部是通過 hchan 結(jié)構(gòu)體來實(shí)現(xiàn)的。這個(gè)結(jié)構(gòu)體包含了通道的基本信息和狀態(tài)UU128資訊網(wǎng)——每日最新資訊28at.com

type hchan struct {    qcount   uint           // 緩沖區(qū)中數(shù)據(jù)的數(shù)量    dataqsiz uint           // 緩沖區(qū)的大小    buf      unsafe.Pointer // 緩沖區(qū)指針    elemsize uint16         // 元素的大小    closed   uint32         // 通道是否關(guān)閉    sendx    uint           // 發(fā)送操作的索引    recvx    uint           // 接收操作的索引    recvq    waitq          // 等待接收的 goroutine 隊(duì)列    sendq    waitq          // 等待發(fā)送的 goroutine 隊(duì)列    lock     mutex          // 保護(hù)通道的互斥鎖}

發(fā)送和接收操作

無緩沖通道

發(fā)送操作

如果沒有接收者,發(fā)送方會(huì)阻塞,直到有接收方開始接收。UU128資訊網(wǎng)——每日最新資訊28at.com

接收操作

如果沒有發(fā)送者,接收方會(huì)阻塞,直到有發(fā)送方開始發(fā)送。UU128資訊網(wǎng)——每日最新資訊28at.com

有緩沖通道

發(fā)送操作

如果緩沖區(qū)未滿,數(shù)據(jù)直接寫入緩沖區(qū)。若緩沖區(qū)已滿,發(fā)送方會(huì)阻塞,直到有空間可用。UU128資訊網(wǎng)——每日最新資訊28at.com

接收操作

如果緩沖區(qū)不為空,數(shù)據(jù)直接從緩沖區(qū)讀取。若緩沖區(qū)為空,接收方會(huì)阻塞,直到有數(shù)據(jù)可讀。UU128資訊網(wǎng)——每日最新資訊28at.com

通道的同步機(jī)制

通道的發(fā)送和接收操作都是原子性的,并且由互斥鎖保護(hù)。這確保了多個(gè) goroutine 同時(shí)操作通道時(shí)不會(huì)發(fā)生競態(tài)條件。UU128資訊網(wǎng)——每日最新資訊28at.com

互斥鎖(Mutex)

每個(gè)通道都有一個(gè)互斥鎖,用于保護(hù)通道的狀態(tài)和數(shù)據(jù)。UU128資訊網(wǎng)——每日最新資訊28at.com

等待隊(duì)列(Wait Queue)

通道維護(hù)兩個(gè)等待隊(duì)列,一個(gè)用于等待接收的 goroutine,一個(gè)用于等待發(fā)送的 goroutine。當(dāng)發(fā)送或接收操作不能立即完成時(shí),goroutine 會(huì)被加入相應(yīng)的等待隊(duì)列中。UU128資訊網(wǎng)——每日最新資訊28at.com

通道關(guān)閉

關(guān)閉通道

通過調(diào)用 close(chan) 可以關(guān)閉通道。關(guān)閉操作會(huì)設(shè)置通道的 closed 標(biāo)志,并喚醒所有在通道上阻塞的發(fā)送和接收操作。UU128資訊網(wǎng)——每日最新資訊28at.com

關(guān)閉后的操作

向已關(guān)閉的通道發(fā)送數(shù)據(jù)會(huì)引發(fā) panic,從已關(guān)閉的通道接收數(shù)據(jù)會(huì)立即返回零值。UU128資訊網(wǎng)——每日最新資訊28at.com

實(shí)現(xiàn)細(xì)節(jié)

以下是通道發(fā)送和接收操作的一些實(shí)現(xiàn)細(xì)節(jié)UU128資訊網(wǎng)——每日最新資訊28at.com

發(fā)送操作

chan send 檢查通道是否關(guān)閉,如果沒有接收者且緩沖區(qū)未滿,數(shù)據(jù)會(huì)被直接寫入緩沖區(qū),否則會(huì)阻塞當(dāng)前 goroutine 并將其加入 sendq。UU128資訊網(wǎng)——每日最新資訊28at.com

接收操作

chan recv 檢查通道是否關(guān)閉或緩沖區(qū)是否為空,如果有數(shù)據(jù)則直接返回,否則阻塞當(dāng)前 goroutine 并將其加入 recvq。UU128資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

Go 語言中的通道通過上述機(jī)制實(shí)現(xiàn)了 goroutine 之間的安全、高效通信。通道的設(shè)計(jì)考慮了并發(fā)編程中的同步問題,通過緩沖機(jī)制和等待隊(duì)列的管理,使得數(shù)據(jù)傳遞和同步操作都能高效地進(jìn)行。UU128資訊網(wǎng)——每日最新資訊28at.com

例子

在 Go 語言中,可以通過 make 函數(shù)來定義通道。根據(jù)是否指定緩沖區(qū)大小,可以創(chuàng)建無緩沖區(qū)通道和有緩沖區(qū)通道。以下是具體的定義和示例:UU128資訊網(wǎng)——每日最新資訊28at.com

無緩沖區(qū)通道

無緩沖區(qū)通道是指在沒有緩沖區(qū)的情況下,發(fā)送和接收操作是同步的。發(fā)送操作會(huì)一直阻塞,直到有接收者接收數(shù)據(jù)。UU128資訊網(wǎng)——每日最新資訊28at.com

定義無緩沖區(qū)通道
ch := make(chan int)
示例
package mainimport (    "fmt")func main() {    ch := make(chan int)    // 啟動(dòng)一個(gè) goroutine 發(fā)送數(shù)據(jù)    go func() {        ch <- 42 // 發(fā)送操作會(huì)阻塞,直到有接收者    }()    // 接收數(shù)據(jù)    value := <-ch    fmt.Println(value) // 輸出: 42}

在這個(gè)例子中,ch 是一個(gè)無緩沖區(qū)通道,發(fā)送操作 ch <- 42 會(huì)阻塞,直到主 goroutine 執(zhí)行 <-ch 接收數(shù)據(jù)。UU128資訊網(wǎng)——每日最新資訊28at.com

有緩沖區(qū)通道

有緩沖區(qū)通道允許在緩沖區(qū)未滿時(shí)發(fā)送操作不會(huì)阻塞,直到緩沖區(qū)滿時(shí)才會(huì)阻塞。UU128資訊網(wǎng)——每日最新資訊28at.com

定義有緩沖區(qū)通道
ch := make(chan int, 3) // 創(chuàng)建一個(gè)緩沖區(qū)大小為 3 的通道
示例
package mainimport (    "fmt")func main() {    ch := make(chan int, 3) // 定義緩沖區(qū)大小為 3 的通道    // 發(fā)送數(shù)據(jù)到通道,不會(huì)阻塞    ch <- 1    ch <- 2    ch <- 3    // 緩沖區(qū)已滿,下面的發(fā)送操作會(huì)阻塞,直到有接收者    go func() {        ch <- 4    }()    // 接收數(shù)據(jù)    fmt.Println(<-ch) // 輸出: 1    fmt.Println(<-ch) // 輸出: 2    fmt.Println(<-ch) // 輸出: 3    fmt.Println(<-ch) // 輸出: 4}

在這個(gè)例子中,ch 是一個(gè)有緩沖區(qū)通道,緩沖區(qū)大小為 3。前 3 個(gè)發(fā)送操作不會(huì)阻塞,直到緩沖區(qū)滿后,第 4 個(gè)發(fā)送操作會(huì)阻塞,直到有接收者開始接收數(shù)據(jù)。UU128資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

通過 make(chan T) 可以創(chuàng)建無緩沖區(qū)通道,通過 make(chan T, capacity) 可以創(chuàng)建有緩沖區(qū)通道。無緩沖區(qū)通道在發(fā)送和接收操作上是同步的,而有緩沖區(qū)通道允許在緩沖區(qū)未滿時(shí)進(jìn)行非阻塞的發(fā)送操作。通過以上示例,可以清晰地看到兩種通道的行為差異。UU128資訊網(wǎng)——每日最新資訊28at.com

select

在 Go 語言中,select 語句用于處理多個(gè)通道的通信操作。它的作用是讓 goroutine 可以同時(shí)等待多個(gè)通道操作(發(fā)送或接收),并在其中任何一個(gè)通道操作完成時(shí)執(zhí)行相應(yīng)的分支代碼。select 語句的使用使得在處理并發(fā)編程時(shí)更加靈活和高效。UU128資訊網(wǎng)——每日最新資訊28at.com

select 語句的基本用法

select 語句的語法與 switch 語句類似,但它專門用于通道操作。每個(gè) case 分支包含一個(gè)通道操作(發(fā)送或接收),select 會(huì)選擇其中一個(gè)已準(zhǔn)備好的通道操作進(jìn)行處理。UU128資訊網(wǎng)——每日最新資訊28at.com

語法結(jié)構(gòu)

select {case expr1:    // 如果 expr1 通道操作可以進(jìn)行,則執(zhí)行此分支case expr2:    // 如果 expr2 通道操作可以進(jìn)行,則執(zhí)行此分支default:    // 如果沒有任何通道操作可以進(jìn)行,則執(zhí)行此分支}

示例:使用 select 同時(shí)等待多個(gè)通道操作

以下是一個(gè)使用 select 語句的示例:UU128資訊網(wǎng)——每日最新資訊28at.com

package mainimport (    "fmt"    "time")func main() {    ch1 := make(chan string)    ch2 := make(chan string)    // 啟動(dòng)第一個(gè) goroutine    go func() {        time.Sleep(2 * time.Second)        ch1 <- "message from ch1"    }()    // 啟動(dòng)第二個(gè) goroutine    go func() {        time.Sleep(1 * time.Second)        ch2 <- "message from ch2"    }()    for i := 0; i < 2; i++ {        select {        case msg1 := <-ch1:            fmt.Println(msg1)        case msg2 := <-ch2:            fmt.Println(msg2)        }    }}

在這個(gè)例子中,有兩個(gè)通道 ch1 和 ch2,每個(gè)通道都在不同的 goroutine 中發(fā)送消息。select 語句使得主 goroutine 可以同時(shí)等待兩個(gè)通道的消息,并在任意一個(gè)通道接收到消息時(shí)執(zhí)行相應(yīng)的分支。UU128資訊網(wǎng)——每日最新資訊28at.com

default 分支

如果在 select 語句中添加了 default 分支,當(dāng)所有通道操作都無法立即進(jìn)行時(shí),會(huì)執(zhí)行 default 分支。這樣可以避免 select 語句阻塞。UU128資訊網(wǎng)——每日最新資訊28at.com

示例:帶有 default 分支的 select

package mainimport (    "fmt"    "time")func main() {    ch := make(chan string)    go func() {        time.Sleep(2 * time.Second)        ch <- "message"    }()    for {        select {        case msg := <-ch:            fmt.Println(msg)            return        default:            fmt.Println("No message received, doing other work")            time.Sleep(500 * time.Millisecond)        }    }}

在這個(gè)例子中,如果通道 ch 上沒有消息可接收,select 會(huì)執(zhí)行 default 分支,打印一條消息并繼續(xù)執(zhí)行其他工作。UU128資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

select 語句是 Go 語言中處理并發(fā)編程的重要工具,通過它可以同時(shí)等待多個(gè)通道操作并在其中一個(gè)操作完成時(shí)進(jìn)行相應(yīng)處理。select 提供了一種靈活且高效的方式來處理多個(gè)通道之間的通信,使得并發(fā)程序的設(shè)計(jì)更加簡潔和直觀。UU128資訊網(wǎng)——每日最新資訊28at.com

等待多個(gè)通道的邏輯

在 Go 語言的 select 語句中,如果有多個(gè)通道操作同時(shí)準(zhǔn)備就緒(即都可以進(jìn)行),Go 運(yùn)行時(shí)會(huì)從這些通道操作中隨機(jī)選擇一個(gè)執(zhí)行。一旦某個(gè)通道操作被選中并執(zhí)行,其它通道的等待操作將不會(huì)繼續(xù)進(jìn)行。每次執(zhí)行 select 語句時(shí)都會(huì)重新評(píng)估所有通道操作。UU128資訊網(wǎng)——每日最新資訊28at.com

示例:多個(gè)通道同時(shí)就緒

為了更好地理解這個(gè)機(jī)制,以下是一個(gè)示例,展示當(dāng)多個(gè)通道同時(shí)準(zhǔn)備就緒時(shí),select 語句的行為:UU128資訊網(wǎng)——每日最新資訊28at.com

package mainimport (    "fmt"    "time")func main() {    ch1 := make(chan string)    ch2 := make(chan string)    ch3 := make(chan string)    go func() {        time.Sleep(1 * time.Second)        ch1 <- "message from ch1"    }()    go func() {        time.Sleep(1 * time.Second)        ch2 <- "message from ch2"    }()    go func() {        time.Sleep(1 * time.Second)        ch3 <- "message from ch3"    }()    for i := 0; i < 3; i++ {        select {        case msg1 := <-ch1:            fmt.Println(msg1)        case msg2 := <-ch2:            fmt.Println(msg2)        case msg3 := <-ch3:            fmt.Println(msg3)        }    }}

在這個(gè)示例中,有三個(gè)通道 ch1, ch2, 和 ch3,每個(gè)通道在 1 秒后發(fā)送一個(gè)消息。因?yàn)樗型ǖ涝谕粫r(shí)間準(zhǔn)備就緒,select 語句將從中隨機(jī)選擇一個(gè)進(jìn)行處理,并打印相應(yīng)的消息。每次循環(huán)都會(huì)重新評(píng)估所有通道。UU128資訊網(wǎng)——每日最新資訊28at.com

結(jié)論

當(dāng) select 語句等待多個(gè)通道時(shí),如果其中一個(gè)通道操作可以進(jìn)行,其它通道的操作不會(huì)繼續(xù)等待,而是等待下一次 select 語句的評(píng)估。每次 select 語句執(zhí)行時(shí)都會(huì)重新評(píng)估所有通道操作,并選擇其中一個(gè)可以進(jìn)行的操作。如果多個(gè)通道同時(shí)就緒,select 會(huì)隨機(jī)選擇其中一個(gè)進(jìn)行處理。UU128資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-91354-0.html深入Go原理:協(xié)程間通信基礎(chǔ)Chan

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: SpringBoot優(yōu)雅定制接口參數(shù)格式轉(zhuǎn)換

下一篇: SpringBoot的自動(dòng)裝配,你學(xué)會(huì)了嗎?

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 一加Ace2 Pro官宣:普及16G內(nèi)存 引領(lǐng)24G

    一加官方今天繼續(xù)為本月發(fā)布的新機(jī)一加Ace2 Pro帶來預(yù)熱,公布了內(nèi)存方面的信息。“淘汰 8GB ,12GB 起步,16GB 普及,24GB 引領(lǐng),還有呢?#一加Ace2Pro#,2023 年 8 月,敬請(qǐng)期待。”同時(shí)
  • Redmi Pad評(píng)測:紅米充滿野心的一次嘗試

    從Note系列到K系列,從藍(lán)牙耳機(jī)到筆記本電腦,紅米不知不覺之間也已經(jīng)形成了自己頗有競爭力的產(chǎn)品體系,在中端和次旗艦市場上甚至要比小米新機(jī)的表現(xiàn)來得更好,正所謂“大丈夫生居
  • Automa-通過連接塊來自動(dòng)化你的瀏覽器

    1、前言通過瀏覽器插件可實(shí)現(xiàn)自動(dòng)化腳本的錄制與編寫,具有代表性的工具就是:Selenium IDE、Katalon Recorder,對(duì)于簡單的業(yè)務(wù)來說可快速實(shí)現(xiàn)自動(dòng)化的上手工作。Selenium IDEKat
  • 從 Pulsar Client 的原理到它的監(jiān)控面板

    背景前段時(shí)間業(yè)務(wù)團(tuán)隊(duì)偶爾會(huì)碰到一些 Pulsar 使用的問題,比如消息阻塞不消費(fèi)了、生產(chǎn)者消息發(fā)送緩慢等各種問題。雖然我們有個(gè)監(jiān)控頁面可以根據(jù) topic 維度查看他的發(fā)送狀態(tài),
  • 量化指標(biāo)是與非:挽救被量化指標(biāo)扼殺的技術(shù)團(tuán)隊(duì)

    作者 | 劉新翠整理 | 徐杰承本文整理自快狗打車技術(shù)總監(jiān)劉新翠在WOT2023大會(huì)上的主題分享,更多精彩內(nèi)容及現(xiàn)場PPT,請(qǐng)關(guān)注51CTO技術(shù)棧公眾號(hào),發(fā)消息【W(wǎng)OT2023PPT】即可直接領(lǐng)取
  • 共享單車的故事講到哪了?

    來源丨海克財(cái)經(jīng)與共享充電寶相差不多,共享單車已很久沒有被國內(nèi)熱點(diǎn)新聞關(guān)照到了。除了一再漲價(jià)和用戶直呼用不起了。近日多家媒體再發(fā)報(bào)道稱,成都、天津、鄭州等地多個(gè)共享單
  • 華為發(fā)布HarmonyOS 4:更好玩、更流暢、更安全

    在8月4日的華為開發(fā)者大會(huì)2023(HDC.Together)大會(huì)上,HarmonyOS 4正式發(fā)布。自2019年發(fā)布以來,HarmonyOS一直以用戶為中心,經(jīng)歷四年多的發(fā)展HarmonyOS已
  • 國行版三星Galaxy Z Fold5/Z Flip5發(fā)布 售價(jià)7499元起

    2023年8月3日,三星電子舉行Galaxy新品中國發(fā)布會(huì),正式在國內(nèi)推出了新一代折疊屏智能手機(jī)三星Galaxy Z Fold5與Galaxy Z Flip5,以及三星Galaxy Tab S9
  • 三星折疊屏手機(jī)去年銷售近1000萬臺(tái) 今年目標(biāo)定為1500萬

    7月29日消息,三星率先發(fā)力可折疊手機(jī)市場,在全球市場已經(jīng)取得了非常亮眼的成績,接下來會(huì)進(jìn)一步鞏固和擴(kuò)大這一優(yōu)勢。三星在推出Galaxy Z Flip5和Galax
Top 主站蜘蛛池模板: 红安县| 酉阳| 文登市| 贡觉县| 卫辉市| 遂宁市| 酉阳| 义马市| 滦南县| 三台县| 龙岩市| 昌吉市| 双牌县| 长阳| 花垣县| 栾城县| 长岛县| 临夏县| 深泽县| 札达县| 吴桥县| 隆德县| 龙岩市| 浦城县| 浦东新区| 宾阳县| 恩平市| 溆浦县| 磐石市| 旅游| 织金县| 贞丰县| 昆山市| 五指山市| 繁昌县| 盐池县| 卢龙县| 潼南县| 衢州市| 托克逊县| 兴山县|