下面这段代码为什么会出现死锁呢?

schrodingercatss · · 925 次点击
应该是和judge通道没关系,是ch通道和wg的问题,主进程你用wg等待子进程执行完成,子进程又在等待主进程的ch读取,所以死锁了 去掉wg就行,改成这样试试 ``` func main() { fmt.Scanf("%d %d", &n, &k) for i := 0; i < n; i++ { fmt.Scanf("%d %d", &arr[i].h, &arr[i].w) } // wg.Add(1) go check() go func() { l, r := 1, 100000 for l < r { mid := (l + r + 1) >> 1 ch <- mid if <-judge { l = mid } else { r = mid - 1 } } ch <- l // wg.Done() }() fmt.Println(<-ch) // wg.Wait() } ```
#2
更多评论
首先输入有问题 简单看下死锁问题,ch写入mid,有可能直接被main中的fmt.Println(<-ch)读取,那么check函数锁死,if <-judge 锁死。 再看,if <-judge在for内,那么可能会读很多次,你check只执行一次即judge只写入一次。 另外,这个好像没有必要用通道吧,按顺序逻辑写就行 ``` package main import "fmt" import "sync" type Node struct { h, w int } var ( arr = make([]Node, 1e5) n, k int ch = make(chan int) judge = make(chan bool) wg sync.WaitGroup ) func check() { tot, num := 0, <-ch for i := 0; i < n; i++ { tot += (arr[i].h / num) * (arr[i].w / num) if tot >= k { judge <- true return } } judge <- false } func main() { fmt.Scanf("%d %d\n", &n, &k) for i := 0; i < n; i++ { fmt.Scanf("%d %d\n", &arr[i].h, &arr[i].w) } wg.Add(1) go func() { l, r := 1, 100000 for l < r { go check() mid := (l + r + 1) >> 1 ch <- mid if <-judge { l = mid } else { r = mid - 1 } } go func(){ ch <- l }() wg.Done() }() wg.Wait() fmt.Println(<-ch) } ```
#1