基础知识:
1.多进程:操作系统层面进行并发的基本模式;
2.多线程:在大部分操作系统上都属于系统层面的并发模式,也是使用最多的最有效的一种模式,相对来说,比多进程开销小很多,然而开发技术在进步,认为多线程开销依旧比较大,且在高并发模式下,影响效率;
3.基于回调的非阻塞/异步IO:多线程模式在实际高并发服务器开发中,会很快耗尽服务器内存和CPU资源,而基于回调的非阻塞/异步IO模式通过事件驱动的方式使用异步IO,使服务器持续运行,且尽可能少用线程,比较有代表性的就是Node.js,但这种模式的编程比多线程更复杂;
4.协程:coroutine,也叫轻量级线程,本质是用户态线程,不需要系统抢占式调度资源,在真正的实现中寄存于线程中,系统开销极小,有效提高线程的任务并发性,也避免多线程的缺点,编程极其简单,结构清晰;
协程的最大优势在于轻量级,或者说协程很廉价,我们可以轻松创建百万个协程而不导致系统资源枯竭崩溃,但线程和进程通常最多不超过1万个!
大多数语言在语法层面不支持协程,而是使用库的形式进行支持,但大都存在缺陷;
Go 从语言层面支持轻量级线程(goroutine)
-----------------------------------------------------------------------
1.简单的并发执行示例
package main
import "fmt"
func Add(x,y int) {
z := x + y
fmt.Println(z)
}
func main(){
for i:=0;i<10;i++ {
go Add(i,i) //启动协程
}
}
//实际执行时,可能没有预想中的10次输出内容,
//原因是还没来得及执行Add,
//mian函数已经结束
//如果仅仅是为了看到输出,
//可以简单的在mian最后使用sleep
2.有并发执行,也会有相应的并发通讯,这是所有语言必须面临和解决的重大课题;
Go语言社区的著名口号:"不要通过共享内存来通信,而应该通过通信来共享内存";
通道:channel,是Go语言在语言级别提供的goroutine协程间的通讯方式。
先看简单的例子
package main
import "fmt"
func Count(ch chan int) {
ch <- 1 //向通道中写入数据,未被读取时,阻塞式
fmt.Println("Counting")
}
func main(){
chs := make([]chan int,10) //创建通道数组
for i:=0;i<10;i++{
chs[i] = make(chan int) //创建通道实例
go Count(chs[i])
}
for _,ch := range(chs) { //迭代遍历
<-ch //从通道中读出数据,没数据可读取时,阻塞式
}
}
未完待续.....