gpt4 book ai didi

go - 如何在不使用 sync.WaitGroup 的情况下防止死锁?

转载 作者:IT王子 更新时间:2023-10-29 02:03:09 25 4
gpt4 key购买 nike

concurrent.go:

package main

import (
"fmt"
"sync"
)

// JOBS represents the number of jobs workers do
const JOBS = 2

// WORKERS represents the number of workers
const WORKERS = 5

func work(in <-chan int, out chan<- int, wg *sync.WaitGroup) {
for n := range in {
out <- n * n
}
wg.Done()
}

var wg sync.WaitGroup

func main() {
in := make(chan int, JOBS)
out := make(chan int, JOBS)

for w := 1; w <= WORKERS; w++ {
wg.Add(1)
go work(in, out, &wg)
}

for j := 1; j <= JOBS; j++ {
in <- j
}
close(in)

wg.Wait()
close(out)
for r := range out {
fmt.Println("result:", r)
}

// This is a solution but I want to do it with `range out`
// and also without WaitGroups
// for r := 1; r <= JOBS; r++ {
// fmt.Println("result:", <-out)
// }
}

例子是 here在 goplay 上。

最佳答案

Goroutines 并发且独立运行。 Spec: Go statements:

A "go" statement starts the execution of a function call as an independent concurrent thread of control, or goroutine, within the same address space.

如果要使用for rangeout channel 接收值,那意味着out channel 只能关闭一次goroutines 已完成发送。

由于 goroutines 并发且独立运行,如果没有同步,您将无法实现这一点。

使用 WaitGroup 是一种方法,一种方法(以确保我们在关闭 out 之前等待所有 goroutine 完成它们的工作)。

您的注释代码是另一种方式:注释代码从 channel 接收的值与 goroutine 应该发送的值一样多,这只有在所有 goroutine 都发送它们的值时才有可能。同步是发送语句和接收操作。

注意事项:

通常从 channel 接收结果是异步完成的,在一个专用的 goroutine 中,或者甚至使用多个 goroutine。这样做,您不需要使用具有能够缓冲所有结果的缓冲区的 channel 。您仍然需要同步来等待所有工作人员完成他们的工作,由于 gorutine 调度和执行的并发和独立性质,您无法避免这种情况。

关于go - 如何在不使用 sync.WaitGroup 的情况下防止死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44179480/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com