Go协程、Go主线程
原先的程序没有并发和并行的概念,没有多核的概念,就是一个进程打天下。后面发现这个效率太低了,就搞出了线程,这样极大的发挥CPU的效率,因为硬件总是比软件发展的快。
现在go考虑的是能不能让多核cpu发挥作用,同时线程就变为逻辑态的,这样线程就变的更加轻量了。
1)Go主线程(有程序员直接称为线程/也可以理解成进程):一个Go线程上,可以起多个协程,你可以这样理解,协程是轻量级的线程。
2)Go协程的特点:
- 有独立的栈空间
- 共享程序堆空间
- 调度由用户控制
- 协程是轻量级的线程
Go 线程-协程
线程虽然好,可以做到并发。但是线程还是比较吃资源,吃资源和占用cpu资源比较多。
现在就是要解决,能不能让cpu全部都参与工作。其次就是线程有点笨重,这样就需要在底层做一些优化,这样线程就变的更加轻巧了。同时在线程之间可以做到资源的共享。
在主线程里面可以跑很多很多的协程,一旦开启了一个协程,它们的数据空间是独立的,协程的开启和终止可以有程序员去控制的。
开启协程,一般以函数为单位进行开启的,如果不使用go test(),直接test()那么就是顺序执行的(即使这两个任务是独立的,也是按照顺序执行,这样任务都在一个CPU上面,往往几个功能之间是需要并行执行的),如果开启了协程就是穿插着执行了。
package mainimport ("fmt""strconv""time"
)func test() {for i := 0; i < 5; i++ {fmt.Println("hello test()" + strconv.Itoa(i))time.Sleep(time.Duration(1) * 1)}
}func main() {//开启了一个协程go test()for i := 0; i < 5; i++ {fmt.Println("hello main()" + strconv.Itoa(i))time.Sleep(time.Duration(1) * 1)}
}hello main()0
hello test()0
hello main()1
hello test()1
hello test()2
hello main()2
hello main()3
hello test()3
hello test()4
hello main()4
输出效果说明,main这个主线程和test协程同时执行。
当执行main的时候就开启了一个主线程,往下执行发现go test(),这样就会开启一个新的分支然后执行,但是主线程并没有阻塞,它会继续往下走,发现for循环去执行,执行完毕主线程就退出。
至于主线程和携程之间如何去通信(因为之间有通信机制),谁先退出,这是两个需要解决的问题。
记住:只要开启了协程就相当于程序多了一个分支。