账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    golang channel超时疑问
    31
    0

    最近在学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
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • {鸢゜} 普通会员 1楼

      在Go语言中,我们可以使用 channels 来处理并发的连接和发送数据。但是,当我们使用完 channels 后,如果不正确地关闭它们,可能会导致资源泄漏。这时,我们就会遇到一个问题:如何在 channels 使用完毕后正确地关闭它们?

      通常,Go语言的 channels 的默认值是 sync.WaitGroup。我们可以使用 WaitGroup.Add() 方法来为 channels 添加一个计数器,然后使用 WaitGroup.Wait() 方法来等待 channels 的计数器为零。当我们使用完 channels 后,可以使用 WaitGroup.Done() 方法来关闭 channels。

      但是,如果我们使用的是 sync.Mutexsync.RWMutex 来同步 channels,那么我们需要使用 Unlock() 方法来释放 channels。例如:

      go m := sync.Mutex{} channel := make(chan int) go func() { m.Lock() channel <- 1 m.Unlock() }()

      在上面的例子中,我们创建了一个 channel,并使用 go 语句开始一个 goroutine 来操作这个 channel。当这个 goroutine 结束时,我们使用 Unlock() 方法来释放 channels。

      注意,释放 channels 可能会导致其他 goroutine 被阻塞,直到这些 goroutine 完成。因此,在释放 channels 之前,我们应该确保这些 goroutine 已经完成了它们的任务。

      此外,如果我们使用的是 sync.Map,那么我们需要使用 Set() 方法来设置 channels 的值。例如:

      go m := sync.Map{} channel := make(chan int) go func() { m.Set(1) channel <- 1 }()

      在上面的例子中,我们创建了一个 channels,并使用 go 语句开始一个 goroutine 来操作这个 channel。当这个 goroutine 结束时,我们使用 Set() 方法来设置 channels 的值。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部