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

Go開發 Channel徹底研究之Select選擇規則

開發 前端
在執行select語句時,運行時系統會自上而下判斷每個case中的發送或接收操作是否可以被立即執行,這里的立即執行的意思是當前goroutine不會因此操作而阻塞。

從左往右,從上往下

對于select的求值,一條case中,從左往右求值;多條case,從上往下,下面舉幾個例子說明:

var ch2 chan int
var ch4 chan int
var chs = []chan int{ch2, ch4}
var numbers = []int{1, 2, 3, 4, 5}
func main() {

select {
case getChan(0) <- getNumber(2):
fmt.Println("1th case is selected")
case getChan(1) <- getNumber(3):
fmt.Println("2th case is selected")
default:
fmt.Println("default!")
}
}
func getChan(i int) chan int {
fmt.Printf("chs[%d]\n",i);
return chs[i]
}
func getNumber(i int) int {
fmt.Printf("numbers[%d]\n",i)
return numbers[i]
}

代碼分析

這段代碼設計的也比較巧妙,調試看出getChan先于getNumber執行,說明一條case中是從左往右求值的;同理,多條case是從上往下執行。

但是有一個問題,我們發現ch2和ch4都是nil,簡化形式如下:

//ch == nil
var ch chan int

select {
case ch <- 0:
default:
fmt.Println("默認執行...")
}

select的case中允許這樣寫,但相當于沒有寫,永遠不會執行。除此外,select中還有很多奇怪的使用方式,再比如:

//無緩沖通道
ch := make(chan int)

select {
case ch <- 0:
default:
fmt.Println("默認執行...")
}

沒有接收方代碼,但是依然也不會錯。

具體運行規則

一、在執行select語句時,運行時系統會自上而下判斷每個case中的發送或接收操作是否可以被立即執行,這里的立即執行的意思是當前goroutine不會因此操作而阻塞。

要點:case中的語句要能立即執行

二、當發現第一個滿足條件的case時,運行時系統就會執行該case所包含的語句,同時,其它case也會被忽略。

要點:只執行一個case

三、如果同時有多個case滿足條件,那么運行時會通過一個偽隨機的算法決定哪一個case將會執行。

要點:多個case同時滿足,使用算法選擇一個

chanCap := 5
ch := make(chan int, chanCap)

for i := 0; i < chanCap; i++ {
select {
case ch <- 1:
case ch <- 2:
case ch <- 3:
}
}

for i := 0; i < chanCap; i++ {
fmt.Printf("%v ", <-ch)
}

代碼分析

這段代碼也很巧妙,驗證了多個case同時滿足條件時,如何進行隨機選擇。

輸出:

3 2 2 2 3
2 1 1 1 2
1 1 3 2 1

可以看出,作者電腦上每次顯示的都是一些隨機選擇。

四、如果所有的case都不能立即執行,且沒有default,那么select會阻塞,直到某個接收或發送的case操作能立即執行。

ch1 := make(chan int)
ch2 := make(chan int)
go func() {
time.Sleep(1 * time.Second)
ch1 <- 10
}()
go func() {
time.Sleep(1 * time.Second)
ch1 <- 20
}()
select {
case d := <-ch1:
fmt.Println(d)
case d := <-ch2:
fmt.Println(d)
}

代碼分析

select等待兩個channel,由于都延時且沒有default,所以select阻塞等待。1s后ch1可以立即執行,因此打印10,select也退出選擇。

五、如果所有通道都是nil且沒有default,且會發生死鎖

// ch1 == nil
var ch1 chan int
select {
case <-ch1:
fmt.Println("hello")
// 沒有default
}

select和for的配合

select和for的搭配有很多問題,本篇只說明一個問題:

select的case中可以使用break,但是只跳出select(區域1),如果想跳出for循環(區域2),需要一些輔助技巧。

總結

介紹了select的一些基本選擇規則,也是需要背誦的知識點。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2023-03-09 09:06:13

ChanneGo開發

2023-05-29 09:25:38

GolangSelect

2021-10-11 11:58:41

Channel原理recvq

2021-10-09 19:05:06

channelGo原理

2023-07-13 08:06:05

應用協程阻塞

2017-04-11 14:45:22

機器學習學習平臺大數據平臺

2024-09-06 10:48:13

2020-12-27 10:15:44

Go語言channel管道

2021-09-01 18:38:59

Goselectdefault

2019-12-10 13:55:10

Go指針存儲

2023-07-27 13:46:10

go開源項目

2023-11-03 18:03:54

Web應用Python

2022-02-22 08:55:29

SelectPoll/ Epoll

2024-06-19 10:08:34

GoChannel工具

2023-12-20 07:30:54

Goselect編程

2020-06-22 07:18:21

Java語言開發

2019-10-17 09:00:00

GoRust編程語言

2011-08-12 09:35:05

javascript

2025-05-20 09:03:58

Go后端Preact

2021-09-30 09:21:28

Go語言并發編程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产九九精品 | 中文字幕一区二区三区四区不卡 | 国产精品视频久久久久 | 日韩在线中文 | 欧美一区二区免费在线 | 成人在线视频免费看 | 欧美一级片在线观看 | 国产日韩久久久久69影院 | 黑人巨大精品欧美黑白配亚洲 | 亚洲精品视频免费 | 中文av在线播放 | 精品久久久久一区二区国产 | 最近中文字幕在线视频1 | 国产午夜精品理论片a大结局 | 欧美日韩在线一区二区 | 欧美一区二区三区在线 | 日本在线播放 | 午夜影院普通用户体验区 | 伊人狠狠干 | 国产无套一区二区三区久久 | h片在线看 | 成人网在线看 | 国产原创在线观看 | 91热爆在线观看 | 亚洲国产精品人人爽夜夜爽 | 一级欧美 | 免费毛片网站在线观看 | 天堂一区 | 999久久久 | 91久久婷婷| www.狠狠干 | av网站免费观看 | 国产视频一视频二 | 日韩高清一区 | 久在线视频播放免费视频 | 精品欧美乱码久久久久久1区2区 | 中文字幕伊人 | 波多野结衣精品在线 | 精产国产伦理一二三区 | 三级视频国产 | 国产综合精品一区二区三区 |