简体   繁体   中英

Why my golang channel raise dead lock error?

package main

import (
    "fmt"
    "sync"
)

func push(c chan int,wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int,wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result,ok := <- c
        fmt.Println(result,ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c,wg)
    go pull(c,wg)

    wg.Wait()
}

Output:

localhost:src kuankuan$ go run goroutine.go 
0 true
1 true
2 true
3 true
4 true
throw: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x42130100, 0x42130100)
    /usr/local/go/src/pkg/runtime/zsema_amd64.c:146 +0x25
sync.(*WaitGroup).Wait(0x42120420, 0x0)
    /usr/local/go/src/pkg/sync/waitgroup.go:79 +0xf2
main.main()
    /Users/kuankuan/go/src/goroutine.go:31 +0xb9

goroutine 2 [syscall]:
created by runtime.main
    /usr/local/go/src/pkg/runtime/proc.c:221
exit status 2

The reason why it deadlocks is because structs are passed by value and not by reference.

When you pass the WaitGroup to your functions, you need to pass the pointer and not the value. Otherwise a copy of the WaitGroup will be used.

This is your working example:

package main

import (
    "fmt"
    "sync"
)

func push(c chan int,wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int,wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result,ok := <- c
        fmt.Println(result,ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c,&wg)
    go pull(c,&wg)

    wg.Wait()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM