Skip to content
lenville edited this page Feb 2, 2015 · 1 revision

终于越过了接口这个坎开始学并发 ( 哦呵呵呵, 人生就是这么艰难, 智商不够就拼时间啊, 倒是拼啊

直接抄书! 句句经典!

"并行是关于性能的, 并发是关于程序设计的" -- Google I/O 2010 ROB PIKE

在Go中使用 channel 和 goroutine 开发并行程序, goroutine 是Go并发能力的核心要素

但是, 什么是 goroutine 啊? 从来没听说过怎么办呢 ...

叫做 goroutine 是因为已有的短语 -- 线程\协程\进程等等 -- 传递不了准确的含义. goroutine 有简单的模型: 它是与其他 goroutine 并行执行的, 有着相同地址空间的函数.. 它是轻量的, 仅比分配栈空间多一点点消耗. 而初始栈是很小的, 所以它们也是廉价的, 并且随着需要在堆空间上分配(和释放). goroutine 是普通的函数, 只是需要使用关键字 go 作为开头

ready("Tea", 2)  // 普通函数调用
go ready("Tea", 2)  // ready() 作为 goroutine 运行

来看这个例子

goroutine 配合 channel 使用是很棒的, 虽然代码里混入了一些奇奇怪怪的东西 比如

<-c
<-c

说实在的, 真的不好看啊 然后作者说可以用 select 来接收 channel 上的消息

L: for {
  select {
  case <-c:
    i++
    if i > 1 {
      break  L
    }
  }
}

就像这样, 就可以应对需要接收多个 channel 值的情况了

goroutine 是并发执行的, 但不是并行运行的. 如果没有额外的配置, Go同一时刻只会有一个 goroutine 执行. 利用 runtime.GOMAXPROCS(n) 可以设置 goroutine 并行执行的数量

GOMAXPROCS 设置了同时运行的CPU的最大数量, 并返回之前的设置. 如果 n<1, 不会改变当前设置. 当调度得到改进后, 这将被移除.

嘛, 来看一个非常赞的特性 ( 这些语言作者脑洞开得都挺大啊, 语言设计得还挺华丽 ... 当然是简约的华丽 这个特性就是 无缓冲channel!!

当在 Go 中用 ch := make(chan bool) 创建 channel 时, bool型 的 无缓冲channel 会被创建 !! 如果读取 (value := <-ch) 它将会被阻塞, 直到有数据接收. 其次, 任何发送 ch<-5 将会被阻塞, 直到数据被读出. 无缓冲channel是在多个 goroutine 之间同步的很棒的工具

所以, 如果想象一个流, 这个流的无缓冲区阻塞就这样实现了. 当然 Go 自然也允许指定 channel 的缓冲区的大小.

ch := make(chan bool, 4)
// 创建了可以存储4个元素的bool型的channel, 这个channel中, 前4个元素可以无阻塞写入, 写入第5个时, 代码被阻塞

然后, 如果 channel 被关闭, 读取端需要知道这个事情. 下面的代码可以检查 channel 是否被关闭

x, ok = <-ch
Clone this wiki locally