Concurrency 为什么这是Go代码死锁?

Concurrency 为什么这是Go代码死锁?,concurrency,go,deadlock,goroutine,Concurrency,Go,Deadlock,Goroutine,所有的goroutine都完成了,但还是会导致死锁。我应该注意的是,无论是否使用计时器,都会死锁。来自: Goexit终止了称之为goroutine的goroutine。没有其他goroutine受到影响。Goexit在终止goroutine之前运行所有延迟调用 你正在退出主要的例行程序。不要。在执行此操作时,在使用go check(i)启动的最后一个例程完成后,没有任何例程运行,因此出现了“死锁”。只需删除此行: Called with 0 Called with 1 Checked 0

所有的goroutine都完成了,但还是会导致死锁。我应该注意的是,无论是否使用计时器,都会死锁。

来自:

Goexit终止了称之为goroutine的goroutine。没有其他goroutine受到影响。Goexit在终止goroutine之前运行所有延迟调用

你正在退出主要的例行程序。不要。在执行此操作时,在使用
go check(i)
启动的最后一个例程完成后,没有任何例程运行,因此出现了“死锁”。只需删除此行:

Called with  0
Called with  1
Checked 0
Called with  2
Checked 1
Called with  3
Checked 2
Called with  4
Woke up 0
Checked 3
Called with  5
Checked 4
Called with  6
Checked 5
Called with  7
Checked 6
Called with  8
Checked 7
Called with  9
Checked 8
Called with  10
Checked 9
Woke up 1
Done for
Checked 10
Woke up 2
Woke up 3
Woke up 4
Woke up 5
Woke up 6
Woke up 7
Woke up 8
Woke up 9
Woke up 10
throw: all goroutines are asleep - deadlock!

goroutine 2 [syscall]:
created by runtime.main
    /tmp/bindist046461602/go/src/pkg/runtime/proc.c:221

goroutine 5 [timer goroutine (idle)]:
created by addtimer
    /tmp/bindist046461602/go/src/pkg/runtime/ztime_amd64.c:69
exit status 2

如果您希望主要等待一组goroutine完成,您可以使用:

主程序包
进口(
“fmt”
“同步”
“时间”
)
func检查(id int,wg*sync.WaitGroup){
格式打印项次(“选中”,id)

你所有的goroutine都在等待有人使用
runtime.Goexit()
使用
发送的值,我在等待其他goroutine完成,它似乎在工作。我的意思是所有的goroutine都运行一行
fmt.Println(“唤醒”)
但它仍然检测到死锁。没有该行,它不会等待其他goroutine完成。这是例程的正常行为。你想做什么?你想在打印“完成”之前完成所有goroutine吗?不,我想
main()
等待其他goroutine完成。这可以在没有
时间的情况下工作。在
行之后。我想知道为什么这会导致死锁。它应该只是阻塞,对吗?谢谢你的代码段。我阅读了关于
WaitGroup
的内容,但我真的想知道为什么上面的代码段在没有
的情况下工作。该值将被丢弃,并成为垃圾collected AFAIK。正如我所说的,无论我是否保留该行或删除该行,它仍然被检测为死锁。你是对的。我测试了它,结果表明你不必调用Goexit,否则它将不会被垃圾收集。
Called with  0
Called with  1
Checked 0
Called with  2
Checked 1
Called with  3
Checked 2
Called with  4
Woke up 0
Checked 3
Called with  5
Checked 4
Called with  6
Checked 5
Called with  7
Checked 6
Called with  8
Checked 7
Called with  9
Checked 8
Called with  10
Checked 9
Woke up 1
Done for
Checked 10
Woke up 2
Woke up 3
Woke up 4
Woke up 5
Woke up 6
Woke up 7
Woke up 8
Woke up 9
Woke up 10
throw: all goroutines are asleep - deadlock!

goroutine 2 [syscall]:
created by runtime.main
    /tmp/bindist046461602/go/src/pkg/runtime/proc.c:221

goroutine 5 [timer goroutine (idle)]:
created by addtimer
    /tmp/bindist046461602/go/src/pkg/runtime/ztime_amd64.c:69
exit status 2
defer runtime.Goexit()
package main

import (
    "fmt"
    "sync"
    "time"
)

func check(id int, wg *sync.WaitGroup) {
    fmt.Println("Checked", id)
    <-time.After(time.Duration(id)*time.Millisecond)
    fmt.Println("Woke up", id)
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i <= 10; i++ {
        wg.Add(1)
        fmt.Println("Called with", i)
        go check(i, &wg)
    }
    wg.Wait()
    fmt.Println("Done for")
}
package main

import "fmt"
//import "runtime"
import "time"


func check(id int) {
    fmt.Println("Checked", id)
    <-time.After(time.Duration(id)*time.Millisecond)
    fmt.Println("Woke up", id)
}

func main() {
    //defer runtime.Goexit()

    for i := 0; i <= 10; i++ {
        fmt.Println("Called with", i)
        go check(i)
    }

    fmt.Println("Done for")
}
package main

import "fmt"
import "time"


func check(id int, c chan bool) {
    fmt.Println("Checked", id)
    time.After(time.Duration(id)*time.Millisecond)
    fmt.Println("Woke up", id)
    c <- true
}

func main() {
    c := make(chan bool)

    for i := 0; i <= 10; i++ {
        fmt.Println("Called with", i)
        go check(i, c)
    }
    var n uint
    for n<10 {
        <- c
        n++
    }
    fmt.Println("Done for")
}