英文:
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()
}
英文:
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
答案1
得分: 23
死锁的原因是因为结构体是按值传递而不是按引用传递。
当将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()
}
英文:
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()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论