接收两次worker.done是否刚需?
来源:11-2 使用Channel等待任务结束

xfcy_晓风残月
2020-12-07
老师您好!
根据您的讲述,在这里我们之所以会阻塞,是因为我们在第一个任务(打印小写字母)完成后,没有goroutine再去接收worker.done发出的东西,所以造成阻塞。
根据您的代码,我做了两个实验:
#实验一# 我们去收整个队列中的最后一个done不就能解决这个问题了,我用-race查看之后也没有数据冲突。
#实验二# 我们去收整个队列的一次done,第二个任务(打印大写字母)发出的done就不理会了,同样也没有出现数据冲突。
代码展示:
func chanDemo() {
var workers [26]worker
for i := range workers {
workers[i] = createWorker(i)
}
for i := range workers {
workers[i].in <- 'a' + i
}
for i := range workers {
workers[i].in <- 'A' + i
}
// 实验二:
//for i := 0; i < len(workers); i++ {
// <-workers[i].done
//}
// 实验一:
<-workers[len(workers)-1].done
}
2回答
-
慕仙908892
2021-04-11
你这样不一定每次都能跑完代码~ 小兄弟~ gorouting 谁先执行完是不一定的。而for循环的意义在于他是从第0个开始检测。10太长,我给你举个5个的例子吧~如果执行完的顺序是 1,2,5, 4, 3.你这样写,后面2个你就跑不完,循环的意义在于他先从第1个开始,1有就输出1 2有了就输出2 3这个时候没有就会等待,因为先执了完了5和4,然后这个时候3有了,输出3,5和4之前执行完了,现在直接就显示4 和 5了 。明白吧~,<-done的意义在于他如果没有值,会在那等待的~,chan你可以把他叫作管道,水管,有进就得有出,如果你把doworker中的 done <- true去掉,他就会deadlock。因为没水进来。GO底层会检测,如果你只有出没有进就会报错。
10 -
ccmouse
2020-12-11
不知道你的实验一和实验二是加在最后还是什么地方。我试了一下加在最后,会报deadlock。可以考虑把完整代码贴一下。
阻塞的问题,的确有很多种解法。我这里必须收这20个(视频中是10个小写,10个大写)done,这是前提,然后再考虑如何不阻塞的收到这20个done
022021-06-22
相似问题
回答 1
回答 1