channel"/>
Go学习:channel
概念
goroutine与goroutine之间的双向通道就是channel
语法
定义
package mainimport "fmt"func chanDemmo() {c := make(chan int)c <- 1c <- 2n := <-cfmt.Println(n)
}func main() {chanDemmo()
}
运行程序,会出现死锁;channel是goroutine与goroutine之间的交互,如果没有goroutine就会出现死锁
package mainimport ("fmt""time"
)func chanDemmo() {c := make(chan int)go func() {for {n := <-cfmt.Println(n)}}()c <- 1c <- 2time.Sleep(time.Millisecond)
}func main() {chanDemmo()
}
加一个sleep是为了把所有的内容都打印出来
chan作为参数
package mainimport ("fmt""time"
)func chanDemmo() {c := make(chan int)go worker(c)c <- 1c <- 2time.Sleep(time.Millisecond)
}func worker(c chan int) {for {n := <-cfmt.Println(n)}
}func main() {chanDemmo()
}
package mainimport ("fmt""time"
)func chanDemmo() {var channels [10]chan intfor i := 0; i < 10; i++ {channels[i] = make(chan int)go worker(i, channels[i])}for i := 0; i < 10; i++ {channels[i] <- i}time.Sleep(time.Millisecond)
}func worker(id int, c chan int) {for {fmt.Printf("Worker %d received %d\n", id, <-c)}
}func main() {chanDemmo()
}
chan作为返回值
返回可收可发的chan
package mainimport ("fmt""time"
)func createChan() chan int {c:=make(chan int)return c
}func chanDemmo() {var channels [10]chan intfor i := 0; i < 10; i++ {channels[i] = createChan()go worker(i, channels[i])}for i := 0; i < 10; i++ {channels[i] <- i}time.Sleep(time.Millisecond)
}func worker(id int, c chan int) {for {fmt.Printf("Worker %d received %d\n", id, <-c)}
}func main() {chanDemmo()
}
返回具体用途的chan
package mainimport ("fmt""time"
)func createChan() chan int {c := make(chan int)return c
}
func createSendChan() chan<- int {c := make(chan int)return c
}func chanDemmo() {var channels [10]chan<- intfor i := 0; i < 10; i++ {channels[i] = createSendChan()// go worker(i, channels[i])}for i := 0; i < 10; i++ {channels[i] <- i}time.Sleep(time.Millisecond)
}func worker(id int, c chan int) {for {fmt.Printf("Worker %d received %d\n", id, <-c)}
}func main() {chanDemmo()
}
我们再createSendChan函数里面规定了返回的chan只能取发数据,如果我们用返回的chan收数据程序会编译不通过
bufferedChan
再最开始的例子里面说,如果没有goroutine来接收,会出现死锁,但是我们可以再创建chan的时候设置一个缓冲区,这样的话,发送内容的时候就会发送到缓冲区里面,只有超出了缓冲区大小时才会出现死锁
不超过缓冲区
package mainfunc main() {bufferedChan()
}func bufferedChan() {c:=make(chan int,3)c <- 1c <- 2c <- 3
}
超过缓冲区
package mainfunc main() {//chanDemmo()bufferedChan()
}func bufferedChan() {c:=make(chan int,3)c <- 1c <- 2c <- 3c <- 3
}
接收bufferedChan数据
package mainimport ("fmt""time"
)func worker(id int, c chan int) {for {fmt.Printf("Worker %d received %d\n", id, <-c)}
}func main() {bufferedChan()
}func bufferedChan() {c:=make(chan int,3)go worker(0,c)c <- 1c <- 2c <- 3c <- 4time.Sleep(time.Millisecond)
}
close chan
判断是否还有数据
package mainimport ("fmt""time"
)func main() {bufferedChan()
}func bufferedChan() {c:=make(chan int,3)go workerClose(0,c)c <- 1c <- 2c <- 3c <- 4close(c)time.Sleep(time.Millisecond)
}func workerClose(id int, c chan int) {for {i,ok := <-cif !ok {break}fmt.Printf("Worker %d received %d\n", id, i)}
}
使用range
package mainimport ("fmt""time"
)func main() {bufferedChan()
}func bufferedChan() {c:=make(chan int,3)go workerClose(0,c)c <- 1c <- 2c <- 3c <- 4close(c)time.Sleep(time.Millisecond)
}func workerClose(id int, c chan int) {for i:= range c{fmt.Printf("Worker %d received %d\n", id, i)}
}
close一定要由发送方去close;如果不进行close的话,程序就会一直收数据直至结束!
更多推荐
Go学习:channel
发布评论