整理自《go语言编程》-第四章
1、并发基础
多进程:多进程是在操作系统层面进行并发的基本模式。同时也是开销最大的模式。在Linux平台上,很过工具链正是采用这种模式在工作。比如某个Web服务器,它会有专门的进程负责网络端口的禁用词语和链接管理,还会有专门的进程负责事务和运算。这种方法的好处在于简单、进程间互不影响,坏处是系统开销大,因为所有的进程都是由内核管理的。 多线程:多线程在大部分操作系统上都属于系统层面的并发模式,也是我们使用最多的最有效的一种模式。目前,我们所见的几乎所有工具链都会使用这种模式。它比多进程的开销小很多,但是其开销依旧比较大,且在高并发模式下,效率会有影响。 基于回调的非阻塞/异步IO:这种架构的诞生实际上来源于月多线程模式的危机。在很多高并发服务器开发实践中,使用多线程模式会很快耗尽服务器的内存和CPU资源。二这种模式通过事件驱动的方式使用异步IO,服务器持续运转,且尽可能少用线程,降低开销,它目前在Node.js中得到了很好的实践,但是使用这种模式,编程比多线程要复杂,因为它把流程做了分割,对于问题的本身反应不够自然。 协程:协程(coroutine)本质上一种用户态线程,不需要操作系统来进行抢占式调度,且在真正的实现中寄存于线程中,因此,系统开销极小,可以有效提高线程的任务并发性,而避免多线程的缺点。使用协程的优点是编程简单,结构清晰;缺点是需要语言的支持,如果不支持,则需要用户在程序中自行实现调度器。
2、协程
执行体是个抽象的概念,在操作系统层面有多个概念与之对应,比如操作系统自己掌握的进程(process)、进程内的线程(thread)以及进程内的协程(coroutine,也叫轻量级线程) 多数语言在语法层面并不直接支持协程,而是通过库的方式支持。 Go语言在语言级别支持轻量级线程,叫goroutine。
3、Goroutine
Goroutine是Go语言中的轻量级线程实现,由Go运行时(runtime)管理。 .go:关键字,函数调用前加go关键字,这次调用就会在一个新的goroutine中并发执行。当被调用的函数返回时,这个goroutine也自动结束。如果不是使用channel接收的话,这个函数的返回值将会被丢弃。
4、并发通信
不管是什么平台、什么编程语言并发都是一个大话题。 在工程上,有两种最常见的并发通信模型:共享数据和消息。 共享数据:多个并发单元分别保存对同一个数据的引用,实现对该数据的共享。被共享的数据可能有多种形式,比如内存数据块、磁盘文件、网络数据等。在实际工程应用中最常见的就是共享内存。 Go语言社区:不要通过共享内存来通信,而应该通过通信来共享内存。 Go语言提供的是另一种通信模型,即以消息机制而非共享内存作为通信方式。
5、Channel
(1)概念 Channel 是Go语言在语言级别提供的goroutine间的通信方式。我们可以使用channel在两个或多个goroutine之间传递消息。 Channel是进程内的通信方式,因此通过channel传递对象的过程和调用函数时参数 传递的行为比较一致,比如可以传递指针等。 Channel是类型相关的,一个channel只能传递一种类型的值。
(2)基本语法 声明形式: Var chanName chan ElementType 例子:var ch chan int 定义channel: Ch := make(chan int) 向channel中写入数据: Ch |