登录
首页 >  Golang >  Go问答

关闭goroutine的位置

来源:stackoverflow

时间:2024-02-28 14:24:24 373浏览 收藏

本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《关闭goroutine的位置》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~

问题内容

我很难理解应该在哪里关闭我的频道。

这段代码大约需要 0.7 秒:

options := [3]string{"0", "1", "2"}
str := fmt.sprintf("%6d ", id)
for j := 0; j < 40000; j++ {
    str += options[rand.intn(3)]
}
str += "\n"

添加 io.writestring 对时间没有影响,所以问题就出在这一点。

我想要大约 100,000 个这样的记录,所以我想放入一个 goroutine。

func main() {
    file, _ := os.Create("myfile.txt")
    ch := make(chan string)
    for i := 0; i < 100000; i++ {
       go generate(i, ch)
    }

    counter := 0
    for result := range ch {
       counter++
       io.WriteString(file, result)
       if counter == 100000 {
           close(ch)
       }
    }
    file.Close()
}

func generate(id int, c chan string) {
    options := [3]string{"0", "1", "2"}
    str := fmt.Sprintf("%6d ", id)
    for j := 0; j < 40000; j++ {
        str += options[rand.Intn(3)]
    }
    str += "\n"
    c <- str
}

据我了解,我正在关闭接收方的通道,这并不理想?另外,这样所有 100,000 个应该首先发送到 goroutine,然后我才能收到任何。我可以在发送生成记录的请求的同时开始接收吗?


解决方案


使用计数器关闭通道并不是一个好的做法。您可以使用 sync.waitgroup。这使您可以更好地控制何时关闭频道:

func main() {

    var wg sync.waitgroup

    ch := make(chan string)
    file, _ := os.create("myfile.txt")

    for i := 0; i < 100000; i++ {
        wg.add(1)

        go func(i int) {
            defer wg.done()

            options := [3]string{"0", "1", "2"}
            str := fmt.sprintf("%6d ", i)
            for j := 0; j < 40000; j++ {
                str += options[rand.intn(3)]
            }
            str += "\n"
            ch <- str
        }(i)
    }

    go func() {
        wg.wait()
        close(ch)
    }()

    for result := range ch {
        io.writestring(file, result)
    }
    file.close()
}

看看这是否能解决您的问题..

func main() {
    file, _ := os.Create("myfile.txt")
    ch := make(chan string)
    wg := new(sync.WaitGroup)
    for i := 0; i < 100000; i++ {
       wg.Add(1)
       go generate(i, ch)
    }

    go func(){wg.Wait();close(ch)}()

    counter := 0
    for result := range ch {
       counter++
       io.WriteString(file, result)

    }
    file.Close()
}

func generate(id int, c chan string) {
    options := [3]string{"0", "1", "2"}
    str := fmt.Sprintf("%6d ", id)
    for j := 0; j < 40000; j++ {
        str += options[rand.Intn(3)]
    }
    str += "\n"
    c <- str
    wg.Done()
}

今天关于《关闭goroutine的位置》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>