并发和并行
并发意味着程序在任意时刻都是同时运行的,在规定时间内多个请求都得到执行和处理,分时操作系统就是一种并发设计。
并行意味着程序在单位时间内是同时运行的,在任一粒度时间内都具备同时执行的能力,最简单的例子就是多台机器并行处理。
协程 coroutine
协程是一种用户态的轻量级线程,操作执行者是用户自身程序。协程的执行是非抢占式多任务处理,由协程主动交出控制权,多个协程可能在一个或多个线程上面运行。
不同语言对协程的支持:
- C++: Boost.Coroutine
- Java: 不支持
- Python: async def(e.g. Discord中向频道用户发送消息)
goroutine
操作系统本身具备并发处理能力,但是进程切换的代价过高。所以Go语言在语言层面再构筑一级调度,将并发的粒度降低(编译器/解释器/虚拟机层面)。
goroutine是建立在线程之上的轻量级的抽象,它允许我们以非常低的代价在同一个地址空间中并行地执行多个函数或者方法。在golang中创建一个goroutine只要使用go+匿名/有名函数的形式就可以启动。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package main
import (
"fmt"
"runtime"
"time"
)
func main() {
for i := 0; i < 1000; i++{
go func(i int) {
for{
fmt.Printf("Hello from" +
"goroutine from %d\n", i)
// 设置或查询可以并发执行的goroutine数目
fmt.Println("GOMAXPROCS=", runtime.GOMAXPROCS(0))
}
}(i)
}
time.Sleep(time.Minute)
}
goroutine特性
- go的执行是非阻塞的,不会等待。
- go后面函数的返回值会被忽略。
- 调度器不能保证多个goroutine的执行次序,所有的goroutine是平等地调度和执行的。
- Go程序会单独为main函数创建一个goroutine