詳解golang channel有無緩沖區(qū)的區(qū)別
有無緩沖的區(qū)別
形象說明一下無緩沖和有緩沖的區(qū)別:
無緩沖是同步的,例如 make(chan int),就是一個送信人去你家門口送信,你不在家他不走,你一定要接下信,他才會走,無緩沖保證信能到你手上。
有緩沖是異步的,例如 make(chan int, 1),就是一個送信人去你家仍到你家的信箱,轉(zhuǎn)身就走,除非你的信箱滿了,他必須等信箱空下來,有緩沖的保證信能進(jìn)你家的郵箱。
channel 無緩沖
例1:
func main() { ch := make(chan int) ch <- 1 // 報(bào)錯,因?yàn)閏h 無緩沖,存一個就必須立即取出來 fmt.Println(<- ch) }
改正:
func main() { ch := make(chan int) go tt(ch) // 開一個 goroutine fmt.Println("我先執(zhí)行1111") fmt.Println(<-ch) // 因?yàn)榍懊骈_了一個 goroutine, 這一行比 go tt(ch) 先執(zhí)行,這里堵塞了,等到 tt(ch) 中的語句執(zhí)行完之后,本行執(zhí)行 // 我先執(zhí)行1111 // 我先執(zhí)行2222 // 1 } func tt(ch chan int) { fmt.Println("我先執(zhí)行2222") ch <- 1 }
例2:
package main import "fmt" func main() { ch := make(chan int) // 無緩沖的channel go unbufferChan(ch) for i := 0; i < 10; i++ { fmt.Println("receive ", <-ch) // 讀出值 } } func unbufferChan(ch chan int) { for i := 0; i < 10; i++ { fmt.Println("send ", i) ch <- i // 寫入值 } } // 輸出 // send 0 // send 1 // receive 0 // receive 1 // send 2 // send 3 // receive 2 // receive 3 // send 4 // send 5 // receive 4 // receive 5 // send 6 // send 7 // receive 6 // receive 7 // send 8 // send 9 // receive 8 // receive 9
channel 帶緩存
例1:
放的速度較快,先放滿了 5 個,阻塞??;取的速度較慢,放了5個才開始取,由于緩沖區(qū)已經(jīng)滿了,所以取出一個之后,才能再次放入;放完了之后雖然緩沖區(qū)關(guān)閉了,但是緩沖區(qū)的內(nèi)容還保留,所以還能繼續(xù)取出
func put(c chan int) { for i := 0; i < 10; i++ { c <- i time.Sleep(100 * time.Millisecond) fmt.Println("->放入", i) } fmt.Println("=所有的都放進(jìn)去了!關(guān)閉緩沖區(qū),但是里面的數(shù)據(jù)不會丟失,還能取出。") close(c) } func main() { ch := make(chan int, 5) go put(ch) for { time.Sleep(1000 * time.Millisecond) data, ok := <-ch if ok == true { fmt.Println("<-取出", data) } else { break } } } // ->放入 0 // ->放入 1 // ->放入 2 // ->放入 3 // ->放入 4 // <-取出 0 // ->放入 5 // <-取出 1 // ->放入 6 // <-取出 2 // ->放入 7 // <-取出 3 // ->放入 8 // <-取出 4 // ->放入 9 // =所有的都放進(jìn)去了!關(guān)閉緩沖區(qū),但是里面的數(shù)據(jù)不會丟失,還能取出。 // <-取出 5 // <-取出 6 // <-取出 7 // <-取出 8 // <-取出 9
例2:一邊存,一邊取
package main import"fmt" var c = make(chan int, 5) func main() { go worker(1) for i := 1; i < 10; i++ { c <- i fmt.Println(i) fmt.Println("cap = ", cap(c), " len = ", len(c)) } } func worker(id int) { for { _ = <-c } } // 運(yùn)行輸出: // 1 // cap = 5 len = 0 // 2 // cap = 5 len = 0 // 3 // cap = 5 len = 1 // 4 // cap = 5 len = 2 // 5 // cap = 5 len = 0 // 6 // cap = 5 len = 1 // 7 // cap = 5 len = 2 // 8 // cap = 5 len = 2 // 9 // cap = 5 len = 0
到此這篇關(guān)于詳解golang channel有無緩沖區(qū)的區(qū)別的文章就介紹到這了,更多相關(guān)golang channel緩沖區(qū)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解如何使用Golang實(shí)現(xiàn)Cron定時任務(wù)
定時任務(wù)是許多應(yīng)用程序中常見的一種需求,它們可以用于執(zhí)行定期的清理任務(wù),發(fā)送通知,生成報(bào)告等,在這篇博客中,我們將介紹如何在Go語言中使用robfig/cron包來實(shí)現(xiàn)Cron定時任務(wù),需要的朋友可以參考下2024-04-04詳解Golang中interface{}的注意事項(xiàng)
學(xué)習(xí)?golang?,對于?interface{}?接口類型,我們一定繞不過,這篇文章咱們就來一起來看看?使用?interface{}?的時候,都有哪些注意事項(xiàng)吧2023-03-03解析Go 標(biāo)準(zhǔn)庫 http.FileServer 實(shí)現(xiàn)靜態(tài)文件服務(wù)
http.FileServer 方法屬于標(biāo)準(zhǔn)庫 net/http,返回一個使用 FileSystem 接口 root 提供文件訪問服務(wù)的 HTTP 處理器。下面通過本文給大家介紹Go 標(biāo)準(zhǔn)庫 http.FileServer 實(shí)現(xiàn)靜態(tài)文件服務(wù)的相關(guān)知識,感興趣的朋友一起看看吧2018-08-08CentOS 32 bit安裝golang 1.7的步驟詳解
Go是Google開發(fā)的一種編譯型,并發(fā)型,并具有垃圾回收功能的編程語言。在發(fā)布了6個rc版本之后,Go 1.7終于正式發(fā)布了。本文主要介紹了在CentOS 32 bit安裝golang 1.7的步驟,文中給出了詳細(xì)的步驟,相信對大家的學(xué)習(xí)和理解具有一定的參考借鑒價值,下面來一起看看吧。2016-12-12golang使用map支持高并發(fā)的方法(1000萬次操作14ms)
這篇文章主要介紹了golang使用map支持高并發(fā)的方法(1000萬次操作14ms),本文給大家詳細(xì)講解,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-11-11