进程和线程
进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。
线程是进程的最小单位,是程序执行的最小单元,是进程的一个执行实例。
- 一个进程可以创建和销毁多个线程
- 同一个进程中的多个线程可以并发执行
- 一个程序至少有一个进程,一个进程至少有一个线程
Go并发编程
go协程
主线程是一个物理线程,直接作用在CPU上,是重量级的,非常耗费资源。
其他编程语言的并发机制是基于线程的,开启过多的线程,耗费资源。
go主线程(有程序员称之为线程,甚至是进程):在一个Go线程上开起多个协程,协程是轻量级的线程,是逻辑态的,对资源的耗费小。
- 有独立的占空间
- 共享程序堆空间
- 调度由用户控制
- 轻松开启上个协程
- 协程是轻量级的线程
并发和并行
- 并发:同一个时间段内执行多个任务(一个人同时和多个人聊天):
1---多
- 并行:同一时刻执行多个任务(多个人同时和一个人聊天)
多---1
Go语言并发通过goroutine
实现,类似线程,用户轻量级的线程,但不是线程
-
goroutine
是Go语言运行时候runtime
调度实现,用户自己开的线程,属于轻量级的线程,更加地高效 。线程是操作系统层面实现的 -
Go提供通道channel在多个
goroutine
进行通信。 -
channel
和goroutine
是实现Go
语言并发模式的基础
MPG模式
Goroutine
的调度模型是MPG
模式,解释为
-
M:操作系统的主线程,是物理线程;可以在一个CPU或者多个上执行
-
P:协程执行需要的上下文环境
-
G:协程
goroutine实现
goroutine
的使用是在调用函数的前面加上关键字go
- 一个
goroutine
必定对应一个函数
1 | // demo |
1 | // 开启单个goroutine |
1 | // 开启多个goroutine |
1 | // 匿名函数 |
GOMAXPROCS
1 | package main |
GOMAXPROCS
参数需要使用多少个OS线程来同时执行Go代码,可设置同时执行的最大CPU数,默认是机器上的CPU核心数
GO
通过runtime.GOMAXPROCS()
函数来设置并发执行时占用的CPU逻辑核心数GO1.5
之后默认使用全部的CPU逻辑核心数
1 | // 先执行完a,再执行b |
操作系统线程和goroutine关系
- 一个操作系统线程对应用户多个的
goroutine
go
程序可以同时使用多个操作系统线程goroutine
和OS
线程是多对多的关系,即m:n
:m个goroutine分配到n个操作系统线程中,比如1000个goroutine分配到8个系统线程中