协程 : Where to close

标签 go concurrency goroutine

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

这段代码大约需要 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
}

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

最佳答案

使用计数器关闭 channel 不是一个好习惯。您可以使用 sync.WaitGroup。这使您可以更好地控制何时关闭 channel :

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()
}

关于协程 : Where to close,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62195623/

相关文章:

java - 日志语句导致简单 Java 代码死锁?

performance - 协程性能

go - 如何正确使用 channel 进行并发 POST API 调用并将数据记录在文件中

binary - 为什么 Go 会为小程序生成大二进制文件?

go - Go中的打印类型参数名称

java - 在 Java 中递增信号量许可

asynchronous - 循环结果时 Golang Chan 挂了

go - 数据存储不会将嵌套结构放入 Go

go - func 的语法 Golang 错误

java - CompletableFuture 如何知道任务是独立的?