One with buffer pipe and without buffer pipe
The last synchronization of the coroutine uses an unbuffered pipeline for synchronization. Unbuffered means that the pipeline has no capacity. You must remove something before you can put it again, otherwise it will be blocked. There is a buffer pipeline that can specify the pipeline capacity, when the pipeline is full, it will be blocked. The use of buffered pipes to communicate with the coroutine will cause asynchronous problems.
Creation of unbuffered pipeline ch := make(chan int)
Creation of a buffered pipeline ch := make(chan int,3)//pipe capacity 3
Two one-way pipeline
One-way pipe can only read or write
package main
import (
"fmt"
)
func readNum(ch <-chan int){
for num := range ch{
fmt.Printf("read num=%d\n",num)
}
}
func writeNum(ch chan<- int){
num := 123
fmt.Printf("write num=%d\n",num)
ch<- num
close(ch)
}
func main() {
ch := make(chan int)
//var wrch chan<- int = ch//只写
//var rach <-chan int = ch//只读
go writeNum(ch)
readNum(ch)
fmt.Println("main")
}
One-way pipes cannot be converted to two-way, and two-way pipes can be converted to one-way.
Three-select multiplexing and timeout mechanism
select is a control structure in Go, similar to the switch statement used for communication. Each case must be a communication operation, either sending or receiving
select randomly executes a runnable case. If there is no case to run, it will block until there is a case to run. A default clause should always be runnable
package main
import (
"fmt"
)
func readNum(ch <-chan int,quit <-chan bool){
for {
select{
case num :=<- ch:
fmt.Printf("read num=%d\n",num)
case <- quit:
fmt.Println("quit")
return
}
}
}
func main() {
ch := make(chan int)
quit := make(chan bool)
go func (ch chan<- int,quit chan<- bool){
var num int
for i:= 1;i<5;i++{
num= i*i*i
ch<- num
}
quit<- true
close(quit)
close(ch)
}(ch,quit)
readNum(ch,quit)
}
Timeout mechanism
package main
import (
"fmt"
"time"
)
func readNum(ch <-chan int){
for {
select{
case num :=<- ch:
fmt.Printf("read num=%d\n",num)
case <- time.After(3*time.Second)://超过三秒没有响应,自动退出
fmt.Println("quit")
return
}
}
}
func main() {
ch := make(chan int)
go func (ch chan<- int){
var num int
for i:= 1;i<5;i++{
num= i*i*i
ch<- num
}
}(ch)
readNum(ch)
}
As a result, when outputting, there is no response, quit is automatically printed, and the blocking state is ended