詳解golang channel有無(wú)緩沖區(qū)的區(qū)別
有無(wú)緩沖的區(qū)別
形象說(shuō)明一下無(wú)緩沖和有緩沖的區(qū)別:
無(wú)緩沖是同步的,例如 make(chan int),就是一個(gè)送信人去你家門口送信,你不在家他不走,你一定要接下信,他才會(huì)走,無(wú)緩沖保證信能到你手上。
有緩沖是異步的,例如 make(chan int, 1),就是一個(gè)送信人去你家仍到你家的信箱,轉(zhuǎn)身就走,除非你的信箱滿了,他必須等信箱空下來(lái),有緩沖的保證信能進(jìn)你家的郵箱。
channel 無(wú)緩沖
例1:
func main() {
ch := make(chan int)
ch <- 1 // 報(bào)錯(cuò),因?yàn)閏h 無(wú)緩沖,存一個(gè)就必須立即取出來(lái)
fmt.Println(<- ch)
}改正:
func main() {
ch := make(chan int)
go tt(ch) // 開(kāi)一個(gè) goroutine
fmt.Println("我先執(zhí)行1111")
fmt.Println(<-ch) // 因?yàn)榍懊骈_(kāi)了一個(gè) goroutine, 這一行比 go tt(ch) 先執(zhí)行,這里堵塞了,等到 tt(ch) 中的語(yǔ)句執(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) // 無(wú)緩沖的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 9channel 帶緩存
例1:
放的速度較快,先放滿了 5 個(gè),阻塞??;取的速度較慢,放了5個(gè)才開(kāi)始取,由于緩沖區(qū)已經(jīng)滿了,所以取出一個(gè)之后,才能再次放入;放完了之后雖然緩沖區(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ù)不會(huì)丟失,還能取出。")
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ù)不會(huì)丟失,還能取出。
// <-取出 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有無(wú)緩沖區(qū)的區(qū)別的文章就介紹到這了,更多相關(guān)golang channel緩沖區(qū)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解如何使用Golang實(shí)現(xiàn)Cron定時(shí)任務(wù)
定時(shí)任務(wù)是許多應(yīng)用程序中常見(jiàn)的一種需求,它們可以用于執(zhí)行定期的清理任務(wù),發(fā)送通知,生成報(bào)告等,在這篇博客中,我們將介紹如何在Go語(yǔ)言中使用robfig/cron包來(lái)實(shí)現(xiàn)Cron定時(shí)任務(wù),需要的朋友可以參考下2024-04-04
詳解Golang中interface{}的注意事項(xiàng)
學(xué)習(xí)?golang?,對(duì)于?interface{}?接口類型,我們一定繞不過(guò),這篇文章咱們就來(lái)一起來(lái)看看?使用?interface{}?的時(shí)候,都有哪些注意事項(xiàng)吧2023-03-03
解析Go 標(biāo)準(zhǔn)庫(kù) http.FileServer 實(shí)現(xiàn)靜態(tài)文件服務(wù)
http.FileServer 方法屬于標(biāo)準(zhǔn)庫(kù) net/http,返回一個(gè)使用 FileSystem 接口 root 提供文件訪問(wèn)服務(wù)的 HTTP 處理器。下面通過(guò)本文給大家介紹Go 標(biāo)準(zhǔn)庫(kù) http.FileServer 實(shí)現(xiàn)靜態(tài)文件服務(wù)的相關(guān)知識(shí),感興趣的朋友一起看看吧2018-08-08
一文帶你了解Go語(yǔ)言中的I/O接口設(shè)計(jì)
I/O?操作在編程中扮演著至關(guān)重要的角色,它涉及程序與外部世界之間的數(shù)據(jù)交換,下面我們就來(lái)簡(jiǎn)單了解一下Go語(yǔ)言中的?I/O?接口設(shè)計(jì)吧2023-06-06
CentOS 32 bit安裝golang 1.7的步驟詳解
Go是Google開(kāi)發(fā)的一種編譯型,并發(fā)型,并具有垃圾回收功能的編程語(yǔ)言。在發(fā)布了6個(gè)rc版本之后,Go 1.7終于正式發(fā)布了。本文主要介紹了在CentOS 32 bit安裝golang 1.7的步驟,文中給出了詳細(xì)的步驟,相信對(duì)大家的學(xué)習(xí)和理解具有一定的參考借鑒價(jià)值,下面來(lái)一起看看吧。2016-12-12
golang使用map支持高并發(fā)的方法(1000萬(wàn)次操作14ms)
這篇文章主要介紹了golang使用map支持高并發(fā)的方法(1000萬(wàn)次操作14ms),本文給大家詳細(xì)講解,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11
Go語(yǔ)言中調(diào)用外部命令的方法總結(jié)
在工作中,我們時(shí)不時(shí)地會(huì)需要在Go中調(diào)用外部命令。本文為大家總結(jié)了Go語(yǔ)言中調(diào)用外部命令的幾種姿勢(shì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-11-11

