Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 我应该在哪个函数中传递WaitGroup?_Go - Fatal编程技术网

Go 我应该在哪个函数中传递WaitGroup?

Go 我应该在哪个函数中传递WaitGroup?,go,Go,我制作了一个简单的代码示例来了解管道的用法,如下所示 package main import ( "fmt" "sync" "time" ) func main() { ch1 := make(chan int, 10) // Use buffered channel so as to avoid clogging ch2 := make(chan string, 10) var wg sync.WaitGroup for i := 0

我制作了一个简单的代码示例来了解管道的用法,如下所示

package main

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

func main() {
    ch1 := make(chan int, 10) // Use buffered channel so as to avoid clogging
    ch2 := make(chan string, 10)
    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func1(i, ch1, &wg)
        go func2(ch1, ch2)
    }
    wg.Wait()
    close(ch1)
    for val := range ch2 {
        fmt.Println(val)
    }
}

func func1(seconds int, ch chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    time.Sleep(time.Duration(seconds) * time.Second)
    fmt.Println(seconds)
    ch <- seconds
}

func func2(ch1 chan int, ch2 chan string) {
    for range ch1 {
        ch2 <- "hello"
    }
    close(ch2)
}
另一个人修改了代码,它开始工作,并将func2放在循环之外,但我希望func1的每次迭代都使用func2

问题 因此,我想了解应该在哪里使用WaitGroup和closech

谢谢。 暂时性 戈朗面

使现代化 根据用户的回答,我更改了代码,现在我得到了预期的输出,但不是这个问题的解决方案,但仍然存在死锁。


您的代码中存在多个问题

在循环中,您将生成多个运行func2的3 goroutine,在func2中,您将数据发送到ch2并调用closech2。这是一个问题。当一个goroutine向ch2发送数据时,另一个goroutine关闭了该通道,这会导致:

panic: close of closed channel

goroutine 6 [running]:
main.func2(0xc00006c000, 0xc000056180)
    /home/projects/go-tuts/pipeline-loop.go:36 +0x72
created by main.main
    /home/projects/go-tuts/pipeline-loop.go:16 +0x10f
exit status 2
一般来说,你不需要多次关闭香奈儿-你只需要在它们全部完成后关闭它们。为此,您需要另一个等待组;您需要将这两个函数传递给WaitGroup

进一步阅读:

更新:

就我个人而言,我使用一种工作模式,将数据产生到同一个通道中,并且在所有工作完成后需要关闭该通道:

for something {
    wg.Add(1)
    go func(i int) {
        work(ch)
        wg.Done()
    }
}

go func() {
    wg.Wait()
    close()
}()
我认为保持API与工作组的清洁是一个好主意,因为工作组关注的是如何同步工作,而不是如何完成工作


我已将您的代码更改为以下模式:

我怀疑您只需要一个通道从ch1读取并写入ch2。创建3个go例程来做同样的事情并没有多大意义,而且最终也会关闭相同的通道突变时间,正如leaf bebop指出的那样,这会引起恐慌

func main() {
    ch1 := make(chan int, 10) // Use buffered channel so as to avoid clogging
    ch2 := make(chan string, 10)
    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func1(i, ch1, &wg)
    }
    go func2(ch1, ch2)
    wg.Wait()
    close(ch1)
    for val := range ch2 {
        fmt.Println(val)
    }
}


您好,谢谢您的及时回复,如果我没有将waitgroup传递给func1,而是将它传递给func2,那不是很好吗?另外,我在哪里放置等待func2 waitgroup,因为我在main中使用它,请您添加您认为应该用于main的代码,这将非常有帮助,这非常有帮助。那么,操场规范还不够好吗?@temporarya根据上下文,我认为该规范已经足够好了。如果你想改进它,你需要深入了解细节这就是我想要表达的感谢,感谢你的及时回复安德鲁,我想你是同一个人,无论如何这是不可能的。但问题是,我希望每个func1的输出都由一个新的func2处理,因为在这个示例代码中,它可能看起来很小,但实际上它是一个webcrawler,func1获取数据,func2处理它以将其存储在DB中。这就是为什么需要它。在您当前的soln中,所有func1输出都会转到同一个通道,因此您无法控制哪个func2处理它们-它们可能最终都会经过同一个通道。也许你需要多个通道,而不仅仅是ch1-每个func1一个通道,那么你不需要等待组-每个func1在完成时只关闭它的chan。只是一个想法。顺便说一句,我不在reddit@andrew-w-phillips如果我创建多个通道,那么我将如何处理它的输出?
for something {
    wg.Add(1)
    go func(i int) {
        work(ch)
        wg.Done()
    }
}

go func() {
    wg.Wait()
    close()
}()
func main() {
    ch1 := make(chan int, 10) // Use buffered channel so as to avoid clogging
    ch2 := make(chan string, 10)
    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func1(i, ch1, &wg)
    }
    go func2(ch1, ch2)
    wg.Wait()
    close(ch1)
    for val := range ch2 {
        fmt.Println(val)
    }
}