一.管道
功能:实现并发线程之间的通信,可以将值从一个线程传递到另一个线程
用法:
- 创建: make(chan val-type)
- 赋初值: channel <- val
- 传递值: val <- channel
示例代码:
package main
import "fmt"
func main() {
messages := make(chan string)
go func() { messages <- "ping"}()
msg := <-messages
fmt.Println(msg)
}
运行输出:
$go run channels.go
ping
二.管道缓存
功能:缓存管道中的数据,使得一个管道可以传递多个缓存值
用法:
- 创建: make(chan val-type, num) // num表示缓冲区大小
- 赋初值: channel <- val
- 值传递: val <- channel
示例代码:
package main
import "fmt"
func main() {
messages := make(chan string, 2)
messages <- "buffered"
messages <- "channel"
fmt.Println(<-messages)
fmt.Println(<-messages)
}
三.管道同步
功能:通过管道来实现线程之间的同步
用法:
- 当线程发现管道输出时值为空时便会阻塞线程,直到另一线程有值输入时才会将其唤醒
示例代码
package main
import "fmt"
import "time"
func worker(done chan bool) {
fmt.Print("working...")
time.Sleep(time.Second)
fmt.Println("done")
done <- true
}
func main() {
done := make(chan bool, 1)
go worker(done)
<-done
}
四.管道定向
功能:作为函数参数时指定管道的传输方向
用法:
示例代码
package main
import "fmt"
func ping(pings chan<- string, msg string) {
pings <- msg
}
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)
}
五.Select选择管道
功能:当有多个因为管道未赋值而被阻塞的情况时,选择最先被响应的那种情况执行
用法
select{
case 阻塞情况:
执行内容
case 阻塞情况:
执行内容
...
}
示例代码
package main
import "time"
import "fmt"
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func(){
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func(){
time.Sleep(time.Second * 2)
c2 <- "two"
}()
for i := 0; i < 1; i++{
select{
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}