本篇文章為大家展示了Channel 怎么在Golang中使用,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
創(chuàng)新互聯(lián)建站網(wǎng)站建設(shè)提供從項(xiàng)目策劃、軟件開發(fā),軟件安全維護(hù)、網(wǎng)站優(yōu)化(SEO)、網(wǎng)站分析、效果評(píng)估等整套的建站服務(wù),主營(yíng)業(yè)務(wù)為網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì),app軟件定制開發(fā)以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。創(chuàng)新互聯(lián)建站深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!channel 是干什么的
意義:channel 是用來通信的
實(shí)際上:(數(shù)據(jù)拷貝了一份,并通過 channel 傳遞,本質(zhì)就是個(gè)隊(duì)列)
channel 應(yīng)該用在什么地方
核心:需要通信的地方
例如以下場(chǎng)景:
通知廣播
交換數(shù)據(jù)
顯式同步
并發(fā)控制
...
記??!channel 不是用來實(shí)現(xiàn)鎖機(jī)制的,雖然有些地方可以用它來實(shí)現(xiàn)類似讀寫鎖,保護(hù)臨界區(qū)的功能,但不要這么用!
channel 用例實(shí)現(xiàn)
超時(shí)控制
// 利用 time.After 實(shí)現(xiàn) func main() { done := do() select { case <-done: // logic case <-time.After(3 * time.Second): // timeout } } func do() <-chan struct{} { done := make(chan struct{}) go func() { // do something // ... done <- struct{}{} }() return done }
取最快的結(jié)果
比較常見的一個(gè)場(chǎng)景是重試,第一個(gè)請(qǐng)求在指定超時(shí)時(shí)間內(nèi)沒有返回結(jié)果,這時(shí)重試第二次,取兩次中最快返回的結(jié)果使用。
超時(shí)控制在上面有,下面代碼部分就簡(jiǎn)單實(shí)現(xiàn)調(diào)用多次了。
func main() { ret := make(chan string, 3) for i := 0; i < cap(ret); i++ { go call(ret) } fmt.Println(<-ret) } func call(ret chan<- string) { // do something // ... ret <- "result" }
限制大并發(fā)數(shù)
// 大并發(fā)數(shù)為 2 limits := make(chan struct{}, 2) for i := 0; i < 10; i++ { go func() { // 緩沖區(qū)滿了就會(huì)阻塞在這 limits <- struct{}{} do() <-limits }() }
for...range 優(yōu)先
for ... range c { do } 這種寫法相當(dāng)于 if _, ok := <-c; ok { do }
func main() { c := make(chan int, 20) go func() { for i := 0; i < 10; i++ { c <- i } close(c) }() // 當(dāng) c 被關(guān)閉后,取完里面的元素就會(huì)跳出循環(huán) for x := range c { fmt.Println(x) } }
多個(gè) goroutine 同步響應(yīng)
利用 close 廣播
func main() { c := make(chan struct{}) for i := 0; i < 5; i++ { go do(c) } close(c) } func do(c <-chan struct{}) { // 會(huì)阻塞直到收到 close <-c fmt.Println("hello") }
非阻塞的 select
select 本身是阻塞的,當(dāng)所有分支都不滿足就會(huì)一直阻塞,如果想不阻塞,那么一個(gè)什么都不干的 default 分支是最好的選擇
select { case <-done: return default: }
for{select{}} 終止
盡量不要用 break label 形式,而是把終止循環(huán)的條件放到 for 條件里來實(shí)現(xiàn)
for ok { select { case ch <- 0: case <-done: ok = false } }
channel 特性
基礎(chǔ)特性
操作 | 值為 nil 的 channel | 被關(guān)閉的 channel | 正常的 channel |
---|---|---|---|
close | panic | panic | 成功關(guān)閉 |
c<- | 永遠(yuǎn)阻塞 | panic | 阻塞或成功發(fā)送 |
<-c | 永遠(yuǎn)阻塞 | 永遠(yuǎn)不阻塞 | 阻塞或成功接收 |
happens-before 特性
無緩沖時(shí),接收 happens-before 發(fā)送
任何情況下,發(fā)送 happens-before 接收
close happens-before 接收
上述內(nèi)容就是Channel 怎么在Golang中使用,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。