尽管“一上手怎么写怎么有”的特性很被初学者喜欢,但实践证明,对于一个实际并发的问题,最好的解决方案是“人工把任务之间如何协作“的方式设计好,再去编码。这也是go对并发问题的设计哲学。见The Zen of Go
go这样的并发设定会带来几个重要的好处:
- 人对一个任务如何被执行的有清晰的认识,而不是“猜测某个地方是不是该加个锁”,“某个地方是不是要同步一下”,“访问一个共享变量时哪个线程先到是随机的”……
- 调度器可以实现的更简单。调度器不用再猜“哪个任务该优先执行了”,“哪个需要更responsive一点”,“哪个吞吐应该更高一点”。
- 任务的切换被大大降低,CPU Cache就不会被刷来刷去的,性能也能得到改善。
go的这种做法源自于程序主要是在“协作”。操作系统用抢占的方式调度并发任务,原因是操作系统不能预先判断其上面跑的是什么程序,多少个程序。所以只能用抢占来保障一个进程不会有意无意饿死其他进程,独霸CPU,因此主要体现“抢”。但对于go(和其他任何的编程语言),其编写的程序是“有共同目标的”,即“如何更有效的处理问题“,所以更体现“协”。
但也有些平台类程序,“抢”和“协”兼有,比如Chrome
对于题目中的代码,这就是个验证“一个错误设计的并发导致hang”的例子而已。实际工程当中永远都不会有人写个并发+无限死循环自己坑自己吧。
题主说的心智负担……嗯,如果一个件事情机器自动无论如何都办不好,人想办法搞定了,这个叫“踏实”。
为了更好的理解并发是什么,建议题主多看看Rob Pike的几个讲演
以及