我试图了解Goroutines中的同步。我这里有一个代码,可以在通道上写入从0到4的数字,完成后,我使用range
从通道读取并打印值。
wg.Wait()
等待并在单独的Goroutine中关闭通道的地方很好用。package main
import "fmt"
import "strconv"
import "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)
}
}
package main
import "fmt"
import "strconv"
import "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)
}
}
据我所知,在第二种情况下,主线程执行停止并等待,但是与在单独的goroutine中执行它有何不同?请帮助我理解这一点。
在第一个程序中,主goroutine创建几个goroutine,其中每个goroutine在通道写入时开始等待。然后,主goroutine创建另一个等待wg.Wait()
的goroutine。主goroutine继续,从通道中读取,这也使所有goroutine逐一启用,然后它们终止,释放goroutine,等待wg.Wait()
。
[在第二个程序中,您再次创建等待通道写入的goroutine,但是这次,主goroutine调用wg.Wait()
。此时,您创建的所有goroutine都在等待通道变为可写状态,而主goroutine正在等待goroutine结束,这意味着死锁[]
将每个goroutine视为一个单独的人(或gopher:https://blog.golang.org/gopher)可能会有所帮助。当您go f()
时,您会得到一个新的人员/角色,并让他们执行该功能。因此,您有5个额外的地鼠正在运行: