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