通道实例
通道是连接并发 goroutine 的管道。可以从一个 goroutine 向通道发送值,并在另外一个 goroutine 中接收到这些值。
使用 make(chan val-type) 创建一个新通道,通道由输入的值传入。使用通道 <- 语法将值发送到通道。这里从一个新的 goroutine 发送 “ping” 到上面的消息通道。
<-channel 语法从通道接收值。在这里,将收到上面发送的 ping 消息并打印出来。当运行程序时 ping 消息通过通道成功地从一个 goroutine 传递到另一个 goroutine 。默认情况下发送和接收块,直到发送方和接收方都准备好。此属性允许在程序结束时等待 ping 消息,而不必要使用任何其他同步。
示例代码:
package main
import "fmt"
func main(){
//创建一个新的通道使用下面的方法
messages := make(chan string)
//发送一个值
go func(){message <- "ping"}()
//接收一个值
msg:= <-messages
fmt.Println(msg)
}
通道缓冲实例
默认情况下,通道是未缓冲的,意味着如果有相应的接收 (<-chan)准备好接收发送的值,它们将只接受发送 (chan<-)。缓冲通道接受有限数量的值,而没有用于这些值的相应接收器。
这里使一个字符串的通道缓冲达到 2 个值。因为这个通道被缓冲,所以可以将这些值发送到通道中,而没有相应的并发接收。
之后可以照常接收这两个值。
代码示例如下:
package main
import "fmt"
func main(){
messages := make(chan string,2)
messages <- "buffered"
messages <- "channel"
fmt.Println(<-messages)
fmt.Println(<-messages)
}
通道同步实例
我们可以使用通道在 goroutine 上同步执行程序。这里有一个使用阻塞接收等待 goroutine 完成示例。
这是将在 goroutine 中运行的函数。 done 通道将用来通知另一个 goroutine 这个函数的工作已经完成,发送值以通知已经完成。
启动一个 goroutine 工作程序,给它一个通知通道。如果从此程序中删除 <-done 行,程序将在工作程序(worker)启动之前退出。
阻止,知道在通道上收到工作程序的通知。
package main
import (
"fmt"
"time"
)
func worker(done chan bool){
fmt.Print("workding...")
time.Sleep(time.Second)
fmt.Println("done")
done <- true
}
func main(){
done := make (chan bool,1)
go worker(done)
<-done
}
通道路线实例
当使用通道作为函数参数的时候,可以指定通道是否仅用于发送或者接收值。这种特殊性增加了程序的类型安全性。
此 ping 功能直接收用于发送值的通道,尝试在此频道上接收将是一个编译时错误。ping 函数接收一个通道接收 ping值,一个接受发送 ping值。
package main
import "fmt"
//只接收通道发送数据
func ping(pings chan <- string,msg string){
pings<-msg
}
//只接收通道接收数据
//pong send
func pong(pings<-chan string,pongs chan<- string){
msg := <- pings
pongs <- msg
}
func main(){
pings := make(chan string,1)
pongs := make(chan string,1)
ping (pings,"passed message")
pong (pings,pongs)
fmt.Println(<-pongs)
}