为什么 goroutine 作为等待组的一部分只 运行 一次
Why does the goroutine only run once as part of a waitgroup
func check(name string) string {
resp, err := http.Get(endpoint + name)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
return string(body)
}
func worker(name string, wg *sync.WaitGroup, names chan string) {
defer wg.Done()
var a = check(name)
names <- a
}
func main() {
names := make(chan string)
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker("www"+strconv.Itoa(i), &wg, names)
}
fmt.Println(<-names)
}
预期的结果是 5 个结果,但只有一个执行并且进程结束。
有什么我想念的吗?新的去。
端点是一个通用的 API 即 returns json
您正在启动 5 个 goroutine,但只从 names
通道读取一次。
fmt.Println(<-names)
第一个通道读取完成后,main()
退出。
这意味着一切都在有时间执行之前停止。
要了解有关频道的更多信息,请参阅“Concurrency made easy" from Dave Cheney:
- If you have to wait for the result of an operation, it’s easier to do it yourself.
- Release locks and semaphores in the reverse order you acquired them.
- Channels aren’t resources like files or sockets, you don’t need to close them to free them.
- Acquire semaphores when you’re ready to use them.
- Avoid mixing anonymous functions and goroutines
- Before you start a goroutine, always know when, and how, it will stop
您启动了 5 个 goroutine,但只读取其中一个的输入。另外,你不是在等待你的 goroutines 结束。
// If there are only 5 goroutines unconditionally, you don't need the wg
for i := 1; i <= 5; i++ {
go worker("www"+strconv.Itoa(i), names)
}
for i:=1;i<=5;i++ {
fmt.Println(<-names)
}
但是,如果您不知道要等待多少个 goroutine,那么等待组是必要的。
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker("www"+strconv.Itoa(i), &wg, names)
}
// Read from the channel until it is closed
done:=make(chan struct{})
go func() {
for x:=range names {
fmt.Println(x)
}
// Signal that println is completed
close(done)
}()
// Wait for goroutines to end
wg.Wait()
// Close the channel to terminate the reader goroutine
close(names)
// Wait until println completes
<-done
func check(name string) string {
resp, err := http.Get(endpoint + name)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
return string(body)
}
func worker(name string, wg *sync.WaitGroup, names chan string) {
defer wg.Done()
var a = check(name)
names <- a
}
func main() {
names := make(chan string)
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker("www"+strconv.Itoa(i), &wg, names)
}
fmt.Println(<-names)
}
预期的结果是 5 个结果,但只有一个执行并且进程结束。 有什么我想念的吗?新的去。 端点是一个通用的 API 即 returns json
您正在启动 5 个 goroutine,但只从 names
通道读取一次。
fmt.Println(<-names)
第一个通道读取完成后,main()
退出。
这意味着一切都在有时间执行之前停止。
要了解有关频道的更多信息,请参阅“Concurrency made easy" from Dave Cheney:
- If you have to wait for the result of an operation, it’s easier to do it yourself.
- Release locks and semaphores in the reverse order you acquired them.
- Channels aren’t resources like files or sockets, you don’t need to close them to free them.
- Acquire semaphores when you’re ready to use them.
- Avoid mixing anonymous functions and goroutines
- Before you start a goroutine, always know when, and how, it will stop
您启动了 5 个 goroutine,但只读取其中一个的输入。另外,你不是在等待你的 goroutines 结束。
// If there are only 5 goroutines unconditionally, you don't need the wg
for i := 1; i <= 5; i++ {
go worker("www"+strconv.Itoa(i), names)
}
for i:=1;i<=5;i++ {
fmt.Println(<-names)
}
但是,如果您不知道要等待多少个 goroutine,那么等待组是必要的。
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker("www"+strconv.Itoa(i), &wg, names)
}
// Read from the channel until it is closed
done:=make(chan struct{})
go func() {
for x:=range names {
fmt.Println(x)
}
// Signal that println is completed
close(done)
}()
// Wait for goroutines to end
wg.Wait()
// Close the channel to terminate the reader goroutine
close(names)
// Wait until println completes
<-done