线程其实分两种:
因此,goroutine 的存在必然是为了换个方式解决操作系统线程的一些弊端 -- 太重 。
太重表现在如下几个方面:
第一:创建和切换太重
操作系统线程的创建和切换都需要进入内核,而进入内核所消耗的性能代价比较高,开销较大;
第二:内存使用太重
一方面,为了尽量避免极端情况下操作系统线程栈的溢出,内核在创建操作系统线程时默认会为其分配一个较大的栈内存(虚拟地址空间,内核并不会一开始就分配这么多的物理内存),然而在绝大多数情况下,系统线程远远用不了这么多内存,这导致了浪费;
另一方面,栈内存空间一旦创建和初始化完成之后其大小就不能再有变化,这决定了在某些特殊场景下系统线程栈还是有溢出的风险。
相对的,用户态的goroutine则轻量得多: