登录
首页 >  Golang >  Go问答

使用sync.WaitGroup在管道中同步goroutine

来源:stackoverflow

时间:2024-02-22 15:12:21 457浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《使用sync.WaitGroup在管道中同步goroutine》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

问题内容

我正在尝试在 go 中实现管道,但存在一个问题,即程序在其余 goroutine 完成之前退出主 goroutine。

请帮助使用等待组解决此问题。

package main

import (
    "fmt"
    "sync"
)

var wg sync.WaitGroup

func main() {
    c1 := make(chan string)
    c2 := make(chan string)

    go sender(c1)
    go removeDuplicates(c1, c2)
    go printer(c2)

    wg.Wait()
}

func sender(outputStream chan string) {
    wg.Add(1)
    wg.Done()

    for _, v := range []string{"one", "one", "two", "two", "three", "three"} {
        outputStream <- v
    }

    close(outputStream)
}

func removeDuplicates(inputStream, outputStream chan string) {
    wg.Add(1)
    wg.Done()

    temp := ""

    for v := range inputStream {
        if v != temp {
            outputStream <- v
            temp = v
        }
    }

    close(outputStream)
}

func printer(inputStream chan string) {
    wg.Add(1)
    wg.Done()

    for v := range inputStream {
        fmt.Println(v)
    }
}

当我在这种情况下使用 time.sleep 时,程序成功运行。


正确答案


使用等待组的首要规则:不要从要等待的 goroutine 中调用 add()wait() 可能会在 add() 之前调用,这不是您所期望的。第二条规则:在最后调用 done(),而不是在开头。因此,修复方法是:

func main() {
    c1 := make(chan string)
    c2 := make(chan string)

    wg.Add(3)

    go sender(c1)
    go removeDuplicates(c1, c2)
    go printer(c2)

    wg.Wait()
}

func sender(outputStream chan string) {
    defer wg.Done()

    for _, v := range []string{"one", "one", "two", "two", "three", "three"} {
        outputStream <- v
    }

    close(outputStream)
}

// etc for other two functions

以上就是《使用sync.WaitGroup在管道中同步goroutine》的详细内容,更多关于的资料请关注golang学习网公众号!

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