gpt4 book ai didi

go - 关于 goroutine 在 goroutine 中的行为

转载 作者:行者123 更新时间:2023-12-01 22:35:20 28 4
gpt4 key购买 nike

我是golang的新手,正在研究goroutine。
我写了一个简单的代码,故意使用 goroutine 来划分数字。
首先,我给出基数并继续除它的数,直到它不能被整除
但是,我改变了go split(n)split(n) ,它不像下面那样工作,这是为什么?

■ 源代码

package main

import (
"flag"
"fmt"
"log"
"net/http"
"os"
"strconv"
)

var next = make(chan int)
var quit = make(chan int)

func divide(n int) {
defer func(){ quit <- 1 }()

fmt.Println("[divide] n = " + strconv.Itoa(n))

r := n % 2
if r == 0 {
next <- n / 2
}
}

func execute() {

fmt.Println("[execute] start")
count := 0
end := false
for !end {
select {
case n := <- next:
count++
fmt.Println("[execute] n = " + strconv.Itoa(n) + ", count = " + strconv.Itoa(count))
go divide(n)
case _ = <- quit:
count--
fmt.Println("[execute] end. count = " + strconv.Itoa(count))
if count <= 0 {
end = true
}
}
}
fmt.Println("complete")
os.Exit(0)
}

func main() {

base := flag.Int("n", 1, "Input the number")
flag.Parse()

if *base <= 0 {
fmt.Println("please more than 1")
os.Exit(0)
}

go execute()
next <- *base

if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndSearver:", err)
}
}

■ 结果(工作正常)
$ go run main.go -n 6
[execute] start
[execute] n = 6, count = 1
[divide] n = 6
[execute] n = 3, count = 2
[execute] end. count = 1
[divide] n = 3
[execute] end. count = 0
complete

■ 结果(不工作)
$ go run main.go -n 6
[execute] start
[execute] n = 6, count = 1
[divide] n = 6

最佳答案

没有 go divide()里面执行:

  • execute() 从 next 读取 channel ,来电divide
  • divide() 等待写入 next
  • execute() 仍在等待 divide() 返回,所以程序现在死锁了。

  • go divide()里面执行:
  • execute() 从 next 读取 channel ,开始 divide在新的 goroutine 中,继续等待
  • divide() 写入 next
  • execute() 从 next 读取, 启动另一个 goroutine 等等。

  • 请注意,只要 divide写信给 next ,它继续写入 quit所以你可能会在一切完成之前收到多条退出消息。

    关于go - 关于 goroutine 在 goroutine 中的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58292253/

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