Concurrent-and-parallel

    go 并发与并行 并发(concurrency) 并发的关注点在于任务切分。举例来说,你是一个创业公司的CEO,开始只有你一个人,你一人分饰多角,一会做产品规划,一会写代码,一会见客户,虽然你不能见客户的同时写代码,但由于你切分了任务,分配了时间片,表现出来好像是多个任务一起在执行。 并行(parallelism) 并行的关注点在于同时执行。还是上面的例子,你发现你自己太忙了,时间分配不过来,于是请了工程师,产品经理,市场总监,各司一职,这时候多个任务可以同时执行了。 GreenThread 用户空间 首先是在用户空间,避免内核态和用户态的切换导致的成本。 由语言或者框架层调度 更小的栈空间允许创建大量实例(百万级别) 几个概念 Continuation 这个概念不熟悉 FP 编程的人可能不太熟悉,不过这里可以简单的顾名思义,可以理解为让我们的程序可以暂停,然后下次调用继续(contine)从上次暂停的地方开始的一种机制。相当于程序调用多了一种入口。 Coroutine 是 Continuation 的一种实现,一般表现为语言层面的组件或者类库。主要提供 yield,resume 机制。 Fiber 和 Coroutine 其实是一体两面的,主要是从系统层面描述,可以理解成 Coroutine 运行之后的东西就是 Fiber。 Goroutine Goroutine 其实就是前面 GreenThread 系列解决方案的一种演进和实现。 首先,它内置了 Coroutine 机制。因为要用户态的调度,必须有可以让代码片段可以暂停/继续的机制。 其次,它内置了一个调度器,实现了 Coroutine 的多线程并行调度,同时通过对网络等库的封装,对用户屏蔽了调度细节。 最后,提供了 Channel 机制,用于 Goroutine 之间通信,实现 CSP 并发模型(Communicating Sequential Processes)。因为 Go 的 Channel 是通过语法关键词提供的,对用户屏蔽了许多细节。其实 Go 的 Channel 和 Java 中的 SynchronousQueue 是一样的机制,如果有 buffer 其实就是 ArrayBlockQueue。

    golang-grammer

    chan nobuff 一个基于无缓存Channels的发送操作将导致发送者goroutine阻塞,直到另一个goroutine在相同的 Channels上执行接收操作,当发送的值通过Channels成功传输之后,两个goroutine可以继续执行 后面的语句。反之,如果接收操作先发生,那么接收者goroutine也将阻塞,直到有另一个 goroutine在相同的Channels上执行发送操作。 buff 带缓存的Channel内部持有一个元素队列。

    golang-grammer

    Go基础语法,方便查阅 包、变量和函数 学习 Go 程序的基本组件 1.包 每个 Go 程序都是由包组成的。 程序运行的入口是包 main。 这个程序使用并导入了包 “fmt” 和 “math/rand” 。 按照惯例,包名与导入路径的最后一个目录一致。例如,”math/rand” 包由 package rand 语句开始。 注意:这个程序的运行环境是确定性的,因此 rand.Intn每次都会返回相同的数字。 (为了得到不同的随机数,需要提供一个随机数种子,参阅 rand.Seed。) package main import ( “fmt” “math/rand” ) func main() { fmt.Println(“My favorite number is”, rand.Intn(10)) } ` 结果 My favorite number is 1 2.导入 这个代码用圆括号组合了导入,这是“打包”导入语句。 同样可以编写多个导入语句,例如: import "fmt" import "math" 不过使用打包的导入语句是更好的形式。 `package main import ( “fmt” “math” )