package main
import "fmt"
func f1(ch chan int) {
for i:=0;i<10;i++{
ch<-i
}
close(ch)
}
func f2(ch1 chan int, ch2 chan int) {
for {
data, ok := <-ch1
if !ok {
break
}
ch2<-data*data
}
close(ch2)
}
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go f1(ch1)
go f2(ch1, ch2)
for res := range ch2{
fmt.Println(res)
}
}
channel
无缓冲通道
package main
import "fmt"
func main() {
// 无缓冲的通道,在放入数据的同时就需要有一个goroutine把数据取走才可以
ch := make(chan int)
go func() {
ch <- 3
}()
fmt.Println(<-ch)
}
有缓冲通道
package main
import "fmt"
func main() {
// 有缓冲的通道,可以存放指定数量的数据,在存储空间未满的时候不需要同时取出
ch := make(chan int, 3)
ch <- 5
ch <- 88
ch <- 29
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
}
单向通道
package main
import "fmt"
// 单向通道,只能往通道里面放入数据
func func1(ch1 chan<- string, msg string) {
ch1<- msg
}
// 单向通道,只能取通道数据
func func2(ch1 <-chan string) {
fmt.Println(<-ch1)
}
func main() {
ch := make(chan string, 1)
func1(ch, "hello")
func2(ch)
}
遍历通道/通道关闭
package main
import "fmt"
func main() {
ch := make(chan int, 10)
for i:=0;i<10;i++ {
ch <- i
}
// 关闭后通道将不能再往里写入数据了,读是可以的
close(ch)
// 使用for遍历通道需要在之前把通道关闭,不然for循环不知道遍历到哪里
for v := range ch {
fmt.Println(v)
}
}
使用通道实现同步
package main
import "fmt"
func worker(flag chan bool) {
fmt.Println("hello world")
flag <- true
}
func main() {
flag := make(chan bool)
go worker(flag)
<- flag
}
实现等待多个goroutine
package main
import "fmt"
func worker(flag chan bool) {
fmt.Println("hello world")
flag <- true
}
func main() {
flag := make(chan bool, 3)
go worker(flag)
go worker(flag)
go worker(flag)
for i:=0; i<3; i++ {
<- flag
}
}
channel & goroutine运行逻辑个人分析
package main
import "fmt"
func main() {
ch := make(chan int, 5)
go func() {
for i:=0;i<5;i++ {
ch <- i
}
}()
for i:=0;i<5;i++{
// 首先程序来到这里会阻塞住程序,这时去执行其它goroutine,也就是上面的匿名函数
// 匿名函数执行完毕后这边的阻塞也就会结束,继续执行,从channel中把数据取出来
fmt.Println(<-ch)
}
}