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

出力:構造体は値ではなく参照によって渡されるためなぜ私のゴランチャンネルがデッドロックエラーを起こすのですか?

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 

答えて

17

それがデッドロックの理由による。

関数にWaitGroupを渡すときは、ポインタを渡す必要があります。それ以外の場合は、WaitGroupのコピーが使用されます。

これはあなたの作業例です:

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() 
} 
関連する問題