并发(Concurrency)不是并行(Parallelism)
并发
- 将相互独立的执行过程综合到一起
- 同时处理很多事情
- 重点在组合
并行
- 同时执行多个计算任务
- 同时能完成很多事情
- 重点在执行
golang的并发
将一个程序分解成小片段独立执行,各个独立的执行任务之间的合作通过通信实现。
golang提供:
- 并发执行(goroutines)
- 通信,同步和消息传输(channels)
- 多路并发控制(select)
一个简单形象的golang经典教程(地鼠烧书):
http://www.vaikan.com/docs/Concurrency-is-not-Parallelism/#landing-slide
Goroutines
A goroutine is a lightweight thread managed by the Go runtime.
go function(x, y, z)
每个goroutine独立执行,互不干扰。
package main
import (
"fmt"
)
func main() {
//每次执行该程序,0~5输出的顺序都不一定一致
//因为每个goroutine独立执行,互不干扰
for i := 0; i < 5; i++ {
go func(i int) {
fmt.Println(i)
}(i)
}
//等待5个goroutine执行完成,
//没有这部分代码会没有输出,因为goroutine独立执行,
//main函数不需要等goroutine执行完就退出了。
var input string
fmt.Scanln(&input)
}
Channels
Channels are a typed conduit through which you can send and receive values with the channel operator, <-.
ch := make(chan int)
...
ch <- v // Send v to channel ch.
v := <-ch // Receive from ch, and
// assign value to v.
By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.
Channels can be buffered. Provide the buffer length as the second argument to make to initialize a buffered channel:
ch := make(chan int, 100)
Select
select 语句使得一个 goroutine 在多个通讯操作上等待。
select 会阻塞,直到条件分支中的某个可以继续执行,这时就会执行那个条件分支。当多个都准备好的时候,会随机选择一个。
当 select 中的其他条件分支都没有准备好的时候,default 分支会被执行。为了非阻塞的发送或者接收,可使用 default 分支:
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
Example - 斐波那契数列
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
参考资料
The Go Programming Language
Effective Go
golang - Concurrency-is-not-Parallelism
有疑问加站长微信联系(非本文作者)