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
之所以陷入僵局,是因为结构是通过值而不是通过引用传递的。
将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() }