从使用上讲
-
goroutine 比线程更轻量级,可以创建十万、百万不用担心资源问题。
-
goroutine 和 chan 搭配使用,实现多线程、高并发 实现起来要方便很多。
-
虽然go的并发用起来很方便,但多线程还是要小心不要产生 数据竞态,以及共享锁还是互斥锁的选择问题、并发操作的数据同步问题(多核心,不同的cpu缓存操作,同步到内存使其他协程感知)。
从实现上讲
-
从资源上讲,线程的栈内存大小一般是固定的一般为2MB,虽然这个数值可以设置,但是 太大了浪费,太小了容易不够用。而 goroutine 栈内存是可变的,初始一般为 2KB,随着需求可以扩大达到1GB。 所以goroutine 十分的轻量级,且能满足不同的需求。
-
从调度上讲,线程的调度由 OS 的内核完成;线程的切换需要CPU寄存器和内存的数据交换,从而切换不同的线程上下文。 其触发方式为 CPU时钟。而goroutine 的调度 则比较轻量级,由go自身的调度器完成;其只关心当前go程序内协程的调度;触发方式为 go内部的事件,time.sleep,通道阻塞,互斥量操作等。
-
协程同线程的关系,有些类似于 线程同进程的关系。多个协成绑定到同一个线程上,按照一定的调度算法执行。