一、select超时检测
package csp import ( "fmt" "testing" "time" ) func service() string { time.Sleep(time.Millisecond * 50) return "Done" } //异步 chan在go中是一个通道有可读可写的chan,也存在只读只写的chan 异步返回 func AsyncService() chan string { //创建接受通道 retCh := make(chan string, 1) go func() { ret := service() fmt.Println("returned result.") //chan放数据 retCh <- ret fmt.Println("service exited.") }() return retCh } //多路选择、超时 func TestSelect(t *testing.T) { //使用select监听 select { case ret := <-AsyncService(): t.Log(ret) // 设置超时等待 case <-time.After(time.Millisecond * 100): t.Error("time out") } }
超时设置为100的执行 === RUN TestSelect returned result. service exited. select_test.go:33: Done --- PASS: TestSelect (0.06s) PASS
超时设置为50 === RUN TestSelect returned result. service exited. select_test.go:36: time out --- FAIL: TestSelect (0.06s) FAIL
二、channel生产者与消费者
package csp import ( "fmt" "sync" "testing" ) //生产者 func dataProducer(ch chan int, wg *sync.WaitGroup) { go func() { for i := 0; i < 10; i++ { //给通道添加数据 ch <- i } //关闭channel,向关闭的channel发送数据,会导致panic close(ch) //ch <- -1 //panic: send on closed channel wg.Done() }() } //消费者 func dataReceiver(ch chan int, wg *sync.WaitGroup) { go func() { for { //从通道取数据,ok为bool值,true表示正常接收,false表示通道关闭 //关闭通道,接收数据,返回零值 if data, ok := <-ch; ok { fmt.Println(data) } else { break } } wg.Done() }() } func TestCloseChannel(t *testing.T) { var wg sync.WaitGroup //创建通道 ch := make(chan int) wg.Add(1) //生成数据 dataProducer(ch, &wg) wg.Add(1) //消费数据 dataReceiver(ch, &wg) wg.Add(1) //消费数据 dataReceiver(ch, &wg) wg.Wait() }
=== RUN TestCloseChannel 0 1 2 3 4 5 6 7 8 9 --- PASS: TestCloseChannel (0.00s) PASS