让 go 堵塞方式的疑问

2021-03-09 11:25:30 +08:00
 hwdef

我想让一个 go 函数永远挺住,目前想到三种方法

for{}
select{}
done := make(chan bool)
<-done

这三种方式有什么区别吗?在 cpu 和内存的使用上呢?

1337 次点击
所在节点    问与答
11 条回复
emSaVya
2021-03-09 11:29:38 +08:00
2 3 会 yield 1 不会
bianzhifu
2021-03-09 13:30:02 +08:00
优先使用 2 简单,代码最少,其次是 3,如果使用 1,可以在 for 里面写一个 time.Sleep(time.Hour)
hwdef
2021-03-09 13:31:06 +08:00
@bianzhifu 这三个在性能上差别大吗
hwdef
2021-03-09 13:32:25 +08:00
@bianzhifu 为什么 3 里面要放一个 sleep 呢
ToPoGE
2021-03-09 13:34:13 +08:00
@hwdef for 肯定是不能用的
baiyi
2021-03-09 14:22:07 +08:00
@hwdef #4 通道阻塞没有人唤醒是不会重新运行的,for 被抢占后还是会被切换回来的。select 有 case 才需要 return,没有 case 会阻塞,所以不用 return,编译器的优化
hwdef
2021-03-09 14:27:21 +08:00
@baiyi 大概了解了,感谢。那我还是用 select 吧,没有唤醒的需求。
boboliu
2021-03-09 14:51:59 +08:00
直接这样写 for 死循环会在 gc 时会因为 for 所在 goroutine 无法被 gc 给抢占,从而卡死整个应用

如果你的 for 内有 call 一些大函数或者用 time.Sleep 的话可以避开这个问题,但是仍然要小心防止无意中写错,所以不如用 chan 或者 sync 包
sunny352787
2021-03-09 14:58:25 +08:00
你该不会是在 main 里面停不下来吧?
hwdef
2021-03-09 15:07:10 +08:00
@boboliu 明白了,感谢
hwdef
2021-03-09 15:07:24 +08:00
@sunny352787 不是 main,一个监听文件变动的函数。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/759904

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX