golang channel超时疑问

最近在学golang,学到协程channel超时这里,想试试多个协程如何判断超时,自己写了下,代码如下:
开了10个协程,很奇怪为什么一半正常输出,一半超时,只是简单输出1秒内应该都能正常输出啊,很疑问,希望有人能解释下。

package main

import (
    "fmt"
    "time"
)

func send(k int, ch chan int) {
    ch <- k
}

func main() {
    fmt.Println(time.Now().Unix())
    ch := make(chan int)
    timeout := make(chan bool)
    for k := 0; k < 10; k++ {
        go send(k, ch)
        go func() {
            time.Sleep(1 * time.Second)
            timeout <- true
        }()
    }

    for i := 0; i < 10; i++ {
        select {
        case <-ch:
            fmt.Println("receive:", <-ch)
        case <-timeout:
            fmt.Println("timeout")
        }
    }

    fmt.Println(time.Now().Unix())
}

/*
1535507000
receive: 1
receive: 3
receive: 5
receive: 7
receive: 9
timeout
timeout
timeout
timeout
timeout
1535507001

*/

阅读 2.4k
1 个回答
case <-ch:
            fmt.Println("receive:", <-ch)

你这里连续取了两次值. 所以只需要五次循环 ch 就已经空了, 后面五次自然都是 timeout 了.

改成:

select {
        case c := <-ch: // 只取一次
            fmt.Println("receive:", c)
        case <-timeout:
            fmt.Println("timeout")
        }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题