为什么我的代码在关闭通道和所有工作人员退出后仍然存在死锁?
Why is there a deadlock in my code even after closing the channel and all workers quitting?
这是我的代码:
package main
import (
"fmt"
"sync"
)
func worker(id int, wg sync.WaitGroup, work <-chan int) {
defer func() {
wg.Done()
fmt.Println("worker", id, "done")
}()
fmt.Println("worker", id, "started")
for w := range work {
fmt.Println("worker", id, "got work", w)
}
}
func main() {
work := make(chan int, 2)
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(i, wg, work)
}
// Generate work and send.
for i := 0; i < 5; i++ {
work <- i
}
close(work)
fmt.Println("waiting ...")
wg.Wait()
fmt.Println("done")
}
这是输出:
worker 2 started
worker 2 got work 0
worker 2 got work 1
worker 2 got work 2
worker 1 started
waiting ...
worker 0 started
worker 0 done
worker 1 got work 4
worker 1 done
worker 2 got work 3
worker 2 done
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc42001409c)
/usr/local/Cellar/go/1.10.2/libexec/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc420014090)
/usr/local/Cellar/go/1.10.2/libexec/src/sync/waitgroup.go:129 +0x72
main.main()
/Users/lone/bar/bar.go:39 +0x15f
exit status 2
为什么会出现这个死锁?
来自文档:
A WaitGroup must not be copied after first use.
尝试将指针传递给辅助函数:
func worker(id int, wg *sync.WaitGroup, work <-chan int)
完整代码如下:Playground
这是我的代码:
package main
import (
"fmt"
"sync"
)
func worker(id int, wg sync.WaitGroup, work <-chan int) {
defer func() {
wg.Done()
fmt.Println("worker", id, "done")
}()
fmt.Println("worker", id, "started")
for w := range work {
fmt.Println("worker", id, "got work", w)
}
}
func main() {
work := make(chan int, 2)
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(i, wg, work)
}
// Generate work and send.
for i := 0; i < 5; i++ {
work <- i
}
close(work)
fmt.Println("waiting ...")
wg.Wait()
fmt.Println("done")
}
这是输出:
worker 2 started
worker 2 got work 0
worker 2 got work 1
worker 2 got work 2
worker 1 started
waiting ...
worker 0 started
worker 0 done
worker 1 got work 4
worker 1 done
worker 2 got work 3
worker 2 done
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc42001409c)
/usr/local/Cellar/go/1.10.2/libexec/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc420014090)
/usr/local/Cellar/go/1.10.2/libexec/src/sync/waitgroup.go:129 +0x72
main.main()
/Users/lone/bar/bar.go:39 +0x15f
exit status 2
为什么会出现这个死锁?
来自文档:
A WaitGroup must not be copied after first use.
尝试将指针传递给辅助函数:
func worker(id int, wg *sync.WaitGroup, work <-chan int)
完整代码如下:Playground