目录
- 有无缓冲的区别
- 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)