- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想了解 Goroutine 中的同步。我这里有一个代码,它在一个 channel 上写入从 0 到 4 的数字,完成后我使用 range
从 channel 读取并打印值。
wg.Wait()
并在单独的 Goroutine 中关闭 channel 时工作正常。package main
import (
"fmt"
"strconv"
"sync"
)
func putvalue(i chan string, value string, wg *sync.WaitGroup) {
i <- value
defer wg.Done()
}
func main() {
queue := make(chan string)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go putvalue(queue, strconv.Itoa(i), &wg)
}
go func() {
wg.Wait()
close(queue)
}()
for elem := range queue {
fmt.Println(elem)
}
}
https://play.golang.org/p/OtaRP3Mm4lk
package main
import (
"fmt"
"strconv"
"sync"
)
func putvalue(i chan string, value string, wg *sync.WaitGroup) {
i <- value
defer wg.Done()
}
func main() {
queue := make(chan string)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go putvalue(queue, strconv.Itoa(i), &wg)
}
wg.Wait()
close(queue)
for elem := range queue {
fmt.Println(elem)
}
}
https://play.golang.org/p/JXmdsdPKQPu
据我所知,在第二种情况下,主线程执行停止并等待,但这与在单独的 goroutine 中执行有何不同?请帮助我理解这一点。
最佳答案
将每个 goroutine 视为一个单独的人(或 gopher:https://blog.golang.org/gopher)可能会有所帮助。当你go f()
你得到一个新的人/地鼠并给他们运行该功能的工作。所以,你有 5 个额外的 gophers 正在运行这个:
func putvalue(i chan string, value string, wg *sync.WaitGroup) {
i <- value
defer wg.Done()
}
5 个中的每一个都运行到它们到达 i <- value
的点线,然后他们停下来,等待 gopher 跑到 channel /邮箱的“获取”一侧,然后伸出手来获取字符串,这是进入 i
的那种包裹。 channel /邮箱。
(另外:defer wg.Done()
应该是函数的第一行,而不是最后一行。或者,将 wg.Done()
作为函数的最后一行。)
现在,如果此时你获得了第六只额外的地鼠并让他这样做:
{
wg.Wait()
close(queue)
}
他会在里面停下来 wg.Wait()
, 等待。
您的主要 gopher 现在继续前往 for
环形。这是从邮箱中读取的,也就是说,现在您的 main gopher 将他的手伸进邮箱/窗口,在 channel 的“get”端。五只等待中的地鼠中的一只终于可以将绳子交到您的地鼠手中了。您的主要 Gopher 获取字符串并将其带回您的 for
环形。被阻止的五个地鼠之一现在可以执行他的 wg.Done()
并过期(大概是去退休地鼠的快乐之地😀)。
您的主要 gopher 在 for
中继续循环,通过邮箱获取更多包裹。当他这样做时,等待邮箱“put”的四只地鼠完成并调用wg.Done()
。 ,它计算工作组计数器。当计数达到零时,不再有等待将包裹放入邮箱的地鼠,但是现在正在 sleep 的地鼠,正在等待wg.Wait()
。 ,被唤醒。所以他很快就会醒来并调用close
.
如果他没有调用close
然而,您的主要 gopher 在等待下一个包裹。所以只有剩下的一只地鼠可以做任何事情:他会完成收盘。或者,也许他醒得很快并且已经关闭了,但如果是这样,您的主要 gopher 已经看到邮箱窗口永远关闭了。无论哪种方式,您的主要 gopher 已经看到或将要看到邮箱窗口( channel )已关闭,并且 for
循环将停止,您的主要地鼠将从 main
返回并前往快乐退休之地。
作为Burak Serdar noted ,虽然,没有单独的地鼠做 wg.Wait()
其次是 close
,这是您的 main gopher 正在执行 wg.Wait()
.所以他从来没有绕过for
循环从(仍然打开的)邮箱/ channel 读取。你的五只地鼠正在 sleep ,等待一只地鼠 Handlebars 伸进邮箱去取他们的包裹。您的主要 gopher 正在 sleep ,等待 sync.WaitGroup
中的柜台下降到零。大家都睡了!
关于go - 与 WaitGroup 的 channel 同步。关闭 channel 和 Waitgroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59638898/
我想了解 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
我是一名优秀的程序员,十分优秀!