不适用 for 循环的话使用 注释部分select
在 select 中区分 取消和超时的操作
package main
import (
"bytes"
"context"
"fmt"
"io"
"os"
"time"
)
func main() {
var res = make(chan string)
var cancelSignal = make(chan string)
go func() {
// 捕获 输入窗口的取消信号
signal := make([]byte, 1)
signalBuffer := bytes.NewBuffer(signal)
if _, err := io.Copy(signalBuffer, os.Stdin); err != nil {
fmt.Println("read err is " + err.Error())
}
cancelSignal <- signalBuffer.String()
}()
// 创建 超时和 取消的context, cancel:取消函数
ctx := context.Background()
ctx, _ = context.WithTimeout(ctx, time.Second * 10)
ctx, cancel := context.WithCancel(ctx)
go test(ctx, res)
/*
select {
case result := <- res:
fmt.Println(result)
case <- ctx.Done():
fmt.Println("超时")
fmt.Println(ctx.Err())
case signal := <- cancelSignal:
fmt.Println(signal)
fmt.Println("取消")
cancel()
fmt.Println(ctx.Err())
}
*/
loop:
for {
select {
case result := <- res:
fmt.Println(result)
break loop
case <- ctx.Done():
fmt.Println(ctx.Err())
break loop
case <- cancelSignal:
fmt.Println("取消")
cancel()
default:
time.Sleep(time.Millisecond)
}
}
}
func test(ctx context.Context, res chan string) {
// create new context
_, _ = context.WithDeadline(ctx, time.Now().Add(time.Second * 20))
time.Sleep(time.Second * 20)
res <- "XYY"
}