成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 語言內置 I/O 多路復用機制

開發 前端
本文我們了解到 select? 中的 case? 語句可以讀取 channel?,多個 case 語句僅能其中 1 個被執行。

01 介紹

Go 協程之間通過 channel 通信,但是 channel 讀寫取決于自身特性,即是否有可寫入緩沖區、緩沖區中是否有數據、是否已關閉...

為了檢測 channel 的特性,Go 提供了一個關鍵字 select,可用于實現 I/O 多路復用機制。

本文我們介紹 Go 關鍵字 select 的使用方式。

02 使用方式

Go 關鍵字 select 中包含 case 語句和 default 語句,其中 default 語句可以認為是一種特殊的 case 語句。

因為 default 語句不負責處理 channel 的讀寫,它可以在 select 中的任意位置,且僅能包含一個 default 語句。在所有 case 語句都不滿足執行條件時,default 語句將被執行(建議盡量不要省略 default 語句)。

我們通過代碼片段,分別介紹 select 在檢測到 channel 不同特性時,得到的運行結果。

空 select

接下來,我們閱讀一段代碼。

func main() {
 fmt.Println("Golang 語言開發棧")
 go func() {
  fmt.Println("Golang 公眾號")
 }()
}

閱讀上面這段代碼,讀者朋友們認為 Go 協程中的打印語句可以正常輸出嗎?

讀者朋友們如果運行代碼,會發現 Go 協程中的打印語句還沒有執行,程序就已經退出了,這是因為 main 函數中的打印語句已經執行完成,所以會退出程序。

如果我們希望 Go 協程中的打印語句也執行,可以在 main 函數中使用 select{} 將 main 阻塞,Go 協程中的打印語句就有機會執行了。但是,這會導致死鎖(可以根據實際應用場景選擇是否使用)。

無緩沖 channel

接下來,我們再讀一段可以導致死鎖的代碼:

func main() {
 c := make(chan string)
 DoChannel(c)
}

func DoChannel(c chan string) {
 var receive string
 send := "golang"
 select {
 case receive = <-c:
  fmt.Println(receive)
 case c <- send:
  fmt.Println(send)
 }
}

閱讀上面這段代碼,我們定義一個函數 DoChannel(),該函數接收的參數是一個 string 類型的 channel,函數體中使用 select 中的兩個 case 語句,分別對參數進行接收和發送操作。

運行代碼,select 阻塞。

因為,我們傳參的 c 是無緩沖 channel,所以它即不能讀也不能寫,兩個 case 語句都不執行,select 陷入阻塞,導致死鎖(此處為了行文,故意沒有 default 語句)。

無數據,有緩沖channel

我們將上面這段代碼,稍微修改一下,將入參的 c 改為 1 個緩沖區大小的 channel(未寫入數據)。代碼如下:

func main() {
 c := make(chan string, 1)
 DoChannel(c)
}

運行代碼,寫執行,讀未執行。

即 select 中的對入參 channel 進行發送操作的 case 語句被執行,因為入參 c 是一個有 1 個緩沖區大小的 channel,并且該 channel 中還沒有數據,所以讀取操作的 case 語句沒有讀取到數據,不滿足執行條件。

有緩沖區,已寫滿數據 channel

我們再修改一下入參 c,將入參的 c 改為 1 個緩沖區大小的 channel,并且寫入字符串 Go。代碼如下:

func main() {
 c := make(chan string, 1)
 c <- "Go"
 DoChannel(c)
}

運行代碼,讀執行,寫未執行。

即 select 中的對入參 channel 進行接收操作的 case 語句被執行,因為入參 c 是一個有 1 個緩沖區大小,并且已寫滿數據,所以讀取操作的 case 語句可以讀取到數據,滿足執行條件。

而寫入操作的 case 無法寫入數據,不滿足執行條件。

有緩沖區,有數據,可寫數據 channel

最后一種場景是既能讀取也能寫入的 channel,我們修改一下入參 c,將入參 c 改為 2 個緩沖區大小的 channel,其中 1 個緩沖區寫入字符串 Go,另外 1 個緩沖區還可以寫入數據。代碼如下:

func main() {
 c := make(chan string, 2)
 c <- "Go"
 DoChannel(c)
}

通過多次運行代碼,會發現讀取和寫入的 case 語句都有機會執行,因為兩個 case 語句都滿足執行條件,但是只能有 1 個 case 語句執行,select 會隨機執行其中 1 個 case 語句。

至此,我們已經介紹了 5 種 channel 在 select 中的運行結果。

case 語句中聲明變量

上面的代碼中,我們發現在兩個 case 語句中,讀操作我們將讀取到的數據賦值給變量 receive,實際上,我們也可以省略變量賦值操作。

如果我們需要將讀取到的數據,賦值給變量的話,一般建議將讀取 channel 返回的兩個值全部接收,其中一個是讀取到的數據,另外一個是布爾值,代表 channel 中沒有數據,并且已被關閉。代碼如下:

func main() {
 c := make(chan string)
 close(c)
 DoChannelV2(c)
}

func DoChannelV2(c chan string) {
 var (
  receive string
  ok      bool
 )
 select {
 case receive, ok = <-c:
  if !ok {
   fmt.Println("no data")
  } else {
   fmt.Println(receive)
  }
 }
}

閱讀上面這段代碼,我們使用 close 將 c 關閉。select 中的讀操作 case 語句,可以通過 ok 的值,得到 channel 中沒有數據,且已被關閉,不必打印空數據。

03 總結

本文我們了解到 select 中的 case 語句可以讀取 channel,多個 case 語句僅能其中 1 個被執行。

每個 case 語句僅能對 1 個 channel 進行讀寫操作,如果讀操作未讀取到數據將陷入阻塞,如果寫操作無法寫入數據將陷入阻塞,如果所有 case 語句中的 channel 都陷入阻塞時,select 也會陷入阻塞。

為了避免 select 陷入阻塞,我們可以使用 default 語句,需要注意的是,default 語句可以在 select 的任意位置,但是僅能包含 1 個,而 case 語句可以包含多個。

責任編輯:武曉燕 來源: Golang語言開發棧
相關推薦

2023-12-06 07:16:31

Go語言語句

2021-03-17 16:53:51

IO多路

2021-02-10 08:09:48

Netty網絡多路復用

2021-03-24 08:03:38

NettyJava NIO網絡技術

2020-10-13 07:51:03

五種IO模型

2020-10-14 09:11:44

IO 多路復用實現機

2025-05-08 08:01:05

2024-12-30 00:00:05

2023-11-08 09:22:14

I/ORedis阻塞

2021-06-09 19:25:13

IODubbo

2022-08-26 00:21:44

IO模型線程

2019-12-23 14:53:26

IO復用

2023-01-09 10:04:47

IO多路復用模型

2011-12-08 10:51:25

JavaNIO

2023-08-07 08:52:03

Java多路復用機制

2021-05-31 06:50:47

SelectPoll系統

2009-06-29 18:09:12

多路復用Oracle

2022-07-11 08:02:15

KafkaSelector

2024-08-08 14:57:32

2023-11-07 08:19:35

IO多路復用磁盤、
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 看一级毛片视频 | 婷婷中文字幕 | 欧美一级片在线观看 | 亚洲欧美一区二区三区视频 | 亚洲毛片在线 | 成年人在线观看 | 欧美性精品 | 91精品一区二区三区久久久久久 | 日韩日韩日韩日韩日韩日韩日韩 | 在线观看中文字幕 | 亚洲欧美一区二区三区国产精品 | 欧美黄在线观看 | 久久综合爱 | 波多野结衣av中文字幕 | 久久久久亚洲 | 精品国产精品国产偷麻豆 | chinese中国真实乱对白 | 久久国产精品视频 | 精品欧美一区二区三区久久久 | 一本色道精品久久一区二区三区 | 精品亚洲国产成av人片传媒 | 亚洲视频在线免费 | 91深夜福利视频 | 亚洲综合小视频 | 九九免费视频 | 欧美日韩综合视频 | 特一级毛片 | 日美女逼逼 | 人干人人 | 久久久久久久亚洲精品 | 久久久久久99 | 蜜桃官网 | 国产精品久久久久久久毛片 | 国产99久久久国产精品 | 久久综合亚洲 | 精品亚洲永久免费精品 | 亚洲视频www | 成人一区二区三区在线 | 天天干天天色 | 黑人粗黑大躁护士 | 毛片视频观看 |