目录
一,Golang的并发编程
在第一篇我们已经提到,golang最重要的一个特色就是他通过go关键字的并发处理。
首先要知道为什么我们需要并发,并发为什么在如今作为一种语言特性如此重要?
关于进程线程,堆栈的基础知识就不赘述(感兴趣可以翻我之前的blog),这里从市场发展需求方面说:1. 一方面, 由于应用程序的迅速增加刺激了用户对于网络产品的依赖,我们既要处理灵敏相应的图形用户界面,又要执行IO和运算,传统串行程序肯定会导致IO阻塞,用户使用体验变差,最后被市场淘汰。 2. 另一方面,事务越来越分配到分布式的环境上,这导致相同的工作单元在不同计算机上处理分片数据,必然要通过线程的切换达到分布式的高性能运转,此时并发成为刚需。
关于并发的实现,
从操作系统的实现模型上发展由多进程->多线程->基于回调的非阻塞/异步和协程机制
关于异步框架已经经受过市场的检验,可以减小消耗,不过编程难度要比多线程大;
协程是用户级线程,开销极小,编程简单结构清晰,不过需要语言的支持(支持的语言很少,比如lua,C#)
golang正是利用在语言级别实现轻量级线程(goroutine),避开java繁琐的多线程框架,成为国内多家公司的当红语言,可以想像简单的多线程处理方式会对服务器方的编写节省多少资源。
二,关于goroutine
我这里讲goroutine就是golang支持的协程
协程的实现:协程是基于线程的。内部实现上,维护了一组数据结构和 n 个线程,真正的执行还是线程,协程执行的代码被扔进一个待执行队列中,由这 n 个线程从队列中拉出来执行。golang 利用并封装了操作系统的异步函数。包括 linux 的 epoll、select 和 windows 的 iocp、event 等,当这些异步函数返回 busy 或 blocking 时,golang 利用这个时机将现有的执行序列压栈,让线程去拉另外一个协程的代码来执行。简单来说,一个线程可以利用队列拥有多个串行执行的协程
协程的特性:在任务调度上,协程是弱于线程的。但是在资源消耗上,协程则是极低的。一个线程的内存在 MB 级别,而协程只需要 KB 级别。而且线程的调度需要内核态与用户的频繁切入