2012-11-26 3 views
7
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() 
} 

Ausgang:Warum mein Golang-Kanal einen Dead-Lock-Fehler auslöst?

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 

Antwort

17

Der Grund, warum es Deadlocks ist, weil structs von Wert und nicht als Verweis übergeben werden. Wenn Sie die WaitGroup an Ihre Funktionen übergeben, müssen Sie den Zeiger und nicht den Wert übergeben. Andernfalls wird eine Kopie der WaitGroup verwendet.

Dies ist Ihr Arbeitsbeispiel:

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() 
} 
Verwandte Themen