目前,我正在将所有值推送到通道中,并从通道中读取数据,然后对其进行平方运算. 我想避免使用time.Sleep(2000 * time.Millisecond),因为它会阻塞执行2秒,相反,我希望每个Goroutine都处理并等待它的执行,然后退出程序.我刚刚和golang 失go 了联系,所以现在问这个基本的问题:有人能帮我这个忙吗?

package main

import (
    "fmt"
    "sync"
    "time"
)

func doSquare(num int) int {
    return num * num
}

var wg sync.WaitGroup

func main() {

    wg.Add(1)
    st := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    quit := make(chan bool)
    ch := make(chan int)
    go func() {
        for i := range st {
            ch <- i
        }
    }()

    go func() {
        for {
            select {
            case x := <-ch:
                fmt.Println(doSquare(x))
                // return

            case <-quit:
                wg.Done()
            default:
                // fmt.Println("---")
                // do something
            }
        }
    }()

    quit <- true

    wg.Wait()
    time.Sleep(2000 * time.Millisecond)
}

推荐答案

只需移动quit <- true到第一个Goroutine的尽头

func main() {
    wg.Add(1)
    st := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    quit := make(chan bool)
    ch := make(chan int)
    go func() {
        for i := range st {
            ch <- i
        }
        quit <- true
    }()

    go func() {
        for {
            select {
            case x := <-ch:
                fmt.Println(doSquare(x))
                // return

            case <-quit:
                wg.Done()
                return
            default:
                // fmt.Println("---")
                // do something
            }
        }
    }()

    wg.Wait()
}

这是另一种表示close(ch)年前没有更多数据的方式

func main() {
    st := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    quit := make(chan bool)
    ch := make(chan int) // improve concurrency by `ch := make(chan int, 100)`
    go func() {
        for i := range st {
            ch <- i
        }
        close(ch)
    }()

    go func() {
        for x := range ch {
            fmt.Println(doSquare(x))
        }
        quit <- true
    }()

    <-quit
}

Go相关问答推荐

Kafka消费者在需要时不会暂停

为什么工具链指令在这种情况下没有效果?

链自定义GRPC客户端拦截器/DialOptions

由docker中的nginx提供的样式和图像在页面上不起作用

为什么 `go mod` 占用了另一个磁盘上的空间而不是我的 GOPATH?

Golang Gorm Fiber - 如何将定义为别名的名称发送到索引模板?

优化方式中所有可能组合的字符串相似度

使用反射在Go中递归迭代 struct 体和集合字段

Golang校验器包:重命名字段错误处理

这是泛型的有效用例吗?

这是实现超时的常见方法,为什么 time.After 不起作用

如何使用 GolangCI 删除未使用的导入

如何将元素从一个切片移动到另一个切片

获取切片元素的地址是否意味着 Go 中元素的副本?

通过环境变量配置 OTLP 导出器

有没有办法将 yaml node 添加到 golang 中现有的 yaml 文档中?

Go 并发、goroutine 同步和关闭通道

Golang SSH客户端错误无法验证,try 的方法[无公钥],没有支持的方法

将基本 HTTP AUth 用户/密码凭据存储在 GO 中,无需外部包

在 etcd 键值存储中禁用历史记录