目录
- 有无缓冲的区别
- channel 无缓冲
- 例1:
- 例2:
- channel 带缓存
- 例1:
- 例2:一边存,一边取
有无缓冲的区别
形象说明一下无缓冲和有缓冲的区别:
无缓冲是同步的,例如 make(chan int),就是一个送信人去你家门口送信,你不在家他不走,你一定要接下信,他才会走,无缓冲保证信能到你手上。
有缓冲是异步的,例如 make(chan int, 1),就是一个送信人去你家仍到你家的信箱,转身就走,除非你的信箱满了,他必须等信箱空下来,有缓冲的保证信能进你家的邮箱。
channel 无缓冲
例1:
func main() {
ch := make(chan int)
ch <- 1 // 报错,因为ch 无缓冲,存一个就必须立即取出来
fmt.Println(<- ch)
}
改正:
func main() {
ch := make(chan int)
go tt(ch) // 开一个 goroutine
fmt.Println("我先执行1111")
fmt.Println(<-ch) // 因为前面开了一个 goroutine, 这一行比 go tt(ch) 先执行,这里堵塞了,等到 tt(ch) 中的语句执行完之后,本行执行
// 我先执行1111
// 我先执行2222
// 1
}
func tt(ch chan int) {
fmt.Println("我先执行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个才开始取,由于缓冲区已经满了,所以取出一个之后,才能再次放入;放完了之后虽然缓冲区关闭了,但是缓冲区的内容还保留,所以还能继续取出
func put(c chan int) {
for i := 0; i < 10; i++ {
c <- i
time.Sleep(100 * time.Millisecond)
fmt.Println("->放入", i)
}
fmt.Println("=所有的都放进去了!关闭缓冲区,但是里面的数据不会丢失,还能取出。")
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
// =所有的都放进去了!关闭缓冲区,但是里面的数据不会丢失,还能取出。
// <-取出 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
}
}
// 运行输出:
// 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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)