- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我做了一个简单的代码示例来理解pipeline的用法,就在这里。
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)
}
现在,问题是我没有得到一致的输出(我知道这是一些并发问题,我还没有完全理解)。
> go run pipeline-loop.go
0
1
2
hello
hello
> go run pipeline-loop.go
0
1
2
hello
hello
hello
> go run pipeline-loop.go
0
1
2
hello
hello
> go run pipeline-loop.go
0
1
2
hello
hello
> go run pipeline-loop.go
0
1
2
hello
hello
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
另一个人更改了代码(并且它正在运行)并将 func2
放在循环之外,但我希望 func1
的每次迭代都使用 func2
>.
所以,我想了解应该在哪里使用 WaitGroup
和 close(ch)
?
谢谢。
暂时的
(一个 golang 菜鸟)
根据用户的回答,我更改了代码,现在我得到了预期的输出(但不是这个问题的解决方案),但仍然存在死锁。 https://play.golang.org/p/O_rp_FLvNh8
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 wg1 sync.WaitGroup
// var wg2 sync.WaitGroup
for i := 0; i < 3; i++ {
wg1.Add(1)
go func1(i, ch1)
go func2(ch1, ch2, &wg1)
}
for val := range ch2 {
fmt.Println(val)
}
wg1.Wait()
close(ch1)
close(ch2)
}
// func func1(seconds int, ch chan<- int, wg *sync.WaitGroup) {
func func1(seconds int, ch chan<- int) {
// defer wg.Done()
time.Sleep(time.Duration(seconds) * time.Second)
fmt.Println(seconds)
ch <- seconds
}
func func2(ch1 chan int, ch2 chan string, wg *sync.WaitGroup) {
defer wg.Done()
for range ch1 {
ch2 <- "hello"
}
}
最佳答案
您的代码中存在多个问题。
在循环中,您生成了多个运行 func2
的 goroutine,在 func2
中,您将数据发送到 ch2
并且调用 close(ch2)
。这是个问题。当一个 goroutine 将数据发送到 ch2
时,另一个 goroutine 可能会关闭该 channel ,这会导致:
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
一般来说,您不需要多次关闭 channel - 您只需要在它们全部完成后关闭它们。为此,您需要另一个 WaitGroup
;您需要将这两个函数都传递给 WaitGroup
。
进一步阅读:https://blog.golang.org/pipelines
更新:
我个人使用一种“工作”模式,将数据生成到同一个 channel 中,并且在所有工作完成后需要关闭该 channel :
for something {
wg.Add(1)
go func(i int) {
work(ch)
wg.Done()
}
}
go func() {
wg.Wait()
close()
}()
我认为让 WorkGroup
中的 API 保持干净是个好主意,因为 WorkGroup
是关于如何同步工作而不是如何完成工作。
我已将您的代码更改为这种模式:https://play.golang.org/p/vdCNsxWhgyQ
关于go - 我应该在哪个函数中传递 WaitGroup?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54624442/
我想了解 Goroutine 中的同步。我这里有一个代码,它在一个 channel 上写入从 0 到 4 的数字,完成后我使用 range 从 channel 读取并打印值。 下面的代码在我等待时使用
我正在尝试使用递归函数查找所有目录的列表。该函数的代码是 func FindDirs(dir string, nativePartitions []int64, wg *sync.WaitGroup,
1. 简介 本文将介绍 Go 语言中的 WaitGroup 并发原语,包括 WaitGroup 的基本使用方法、实现原理、使用注意事项以及常见的使用方式。能够更好地理解和应用 WaitGrou
这个问题在这里已经有了答案: golang - Content of a pointer in a slice changes during recursive function run (1 个回答
我做了一个简单的代码示例来理解pipeline的用法,就在这里。 package main import ( "fmt" "sync" "time" ) func main()
谁能给我一个简单的示例代码来告诉我如何Wait Group有效或可以实现(如果给出例如 this 会更好)?谢谢。 最佳答案 我认为您的示例无法实现 WaitGroup (或同步互斥锁)。 关于go
我用 Go 编写了一些代码来解析站点并检索所有链接及其 Http 响应。我的代码运行良好,但我想添加 GoRoutines 以查看它在递归函数中的工作方式。 package main import (
我编写了以下代码,以便运行直到有人手动退出程序。 确实是 -----每1秒检查一次是否存在 -----如果可用则读取文件并逐行打印文件内容 为此,我首先从 main 调用了一个函数然后我调用一个 Wa
我遇到了一些并发问题。我是第一次编写并发应用程序。 我正在努力实现的目标 依赖函数(使用 goroutines)即 func2 依赖于 func1 问题 如果我在完成waiting后重用waitgro
在下面的代码中,如果其中一个启动的 go 例程花费太长时间(例如 > 10 秒)完成,我如何添加适当的超时错误处理?请注意,我不想有一个“整体”超时,而是每个 go 例程的超时,这样我也可以在我的错误
我已经在stdout和stderr goroutine中添加了以下内容(Go func()…),以等待获取output并完成error。 现在我希望外部函数将等待,直到两个例程都完成为止。 func
我想了解我围绕 WaitGroups 的逻辑是否正确,并看看是否有更有效的方式来构建我的代码。目的是尽可能快地执行任务。 我的代码填充了 _urls通过标准输入填充的 channel 。然后我启动了两
在我的 Go 程序中,我为每个部门启动了多个工作组。 我想在退出程序之前等待每个部门的工作人员完成 我不能使用单个 WaitGroups,因为在实际场景中,我可能必须结束任何特定部门并且只需要等待。
func check(name string) string { resp, err := http.Get(endpoint + name) if err != nil {
我有这个简单的脚本,试图遍历文件系统并逐行读取文件以匹配正则表达式上的行: package main import ( "bufio" "fmt" "io/ioutil" "log"
我之前在goroutine中使用sync.WaitGroup,但是我想控制goroutine并发性, 所以我用并发限制写我的等待组: package wglimit import ( "syn
可能是我看不到明显的东西,我做错了什么: func printSize (listOfUrls []string){ var wg sync.WaitGroup wg.Add(len(
可能是我看不到明显的东西,我做错了什么: func printSize (listOfUrls []string){ var wg sync.WaitGroup wg.Add(len(
我正在尝试并行运行递归快速排序调用: func quicksort(a []int) { quicksortRecursive(a) wg.Wait() insertionso
我有一个依赖于并发检查某些错误的函数,我正在尝试使用 WaitGroup 等待所有返回可能错误的进程完成,然后再检查所有错误。 它似乎跳过了一些 wg.Done() cals。这是调试的 youtub
我是一名优秀的程序员,十分优秀!