Golang并发编程、串行编程
线程概要
1、什么是进程,线程,多线程?
1 | 开个QQ,开了一个进程;开了迅雷,开了一个进程。 |
进程: 一个正在运行的程序一般就是一个进程,一个进程中可以有多个线程
线程:一条有序的CPU命令的集合体
多线程:多条有序CPU命令的集合体
备注:一个CPU在同一时刻只能执行一个CPU命令
2、一个CPU可以并发编程(多线程)吗?
例如:3个线程:(上下文切换->线程切换(时间片轮转)) 并发编程
线程1: 5个命令
线程2: 3个命令
线程3: 8个命令
线程1、线程2、线程3在一个CPU的情况下,进行并发编程,由于CPU在同一时间只能执行一个命令,
所以需要通过时间片的轮转
3、并发/并行编程、串行编程
并发编程:多个线程,会有时间片的分配问题,多个线程之间会不断的来回切换
串行编程:按照顺序一一的去执行
4、CPU有分类:
CPU分为两种:物理CPU、逻辑CPU
- 一个物理CPU可以虚拟出多个逻辑CPU(多核)
- 8核同一时刻可以最多执行八个cup命令
5、多线程编程优缺点:
优点:分线程可以处理耗时操作,不会出现主线程阻塞
缺点:资源竞争,内存消耗,死锁
golang多线程
1、创建多线程:
- 多线程通过 go 关键字创建分线程
- 引入
sync
库控制多线程,var wg sync.WaitGroup
创建实例。wg.Add()
方法声明分线程数。wg.Wait()
方法等待声明的线程全部执行完时(线程数为0时),才会执行后续代码; 在每个分线程。wg.Done()
表示该分线程执行结束,告知主线程(每当分线程执行结束,wg.Add()
声明的线程数减一)。
1 | package main |
2、资源竞争、上锁
并发编程由于是CPU在多个线程建来回切换,如果多个线程对同一全局变量进行操作,则无法预测出现的结果(因为CPU在多线程间的切换是随机的)。这时就需要对数据进行上锁,即同一时刻,同一数据只能被一个线程操作。当操作时对该数据上锁,在此期间,其他线程无法操作该数据,只能等待。当该数据的操作完成时,再对其进行解锁,这样等待中的其他线程就可以操作该数据。
检测资源竞争:go run -race main.go
1 | package main |
Golang并发编程、串行编程