并发:一个时间段内,多个程序在一个CPU上运行,但任意时刻只有一个程序在运行
并行:基于多内核,在任意时刻多个程序运行在多个CPU上,彼此互不干扰
在并发里的程序运行方式:
- 多进程:利用计算机多CPU的特性,创建多个进程,彼此互不干扰,常用python库multiprocessing,但是创建进程需要占用一定的运行空间,开销较大
- 多线程:依附于进程,不占用资源,如果只有一个CPU,是无法实现在某一时刻处理多个线程,常用的python库是threading,但是python因为GIL全局锁的存在,使得多线程只能在一个CPU上运行,线程之间需要抢占GIL全局锁,也就是同一时间只有只能运行一个线程,并没有利用计算机多CPU的优势
- 协程:依附于线程,不涉及GIL全局锁开销更小,切换的顺序可控,常用python库gevent,evelet,asyncio
举个简单例子说明多进程和多线程:
- 多进程:我们的计算机可以使用微信,浏览器,QQ等功能
- 多线程:在浏览器上我们可以一遍看文章,一遍听歌,一边下载小说
from multiprocessing import Pool
import os, time
def fun(id):
print('Run task %s (%s)...' % (id, os.getpid()))
time.sleep(5)
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(fun, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
# 进程池可同时处理4个进程,现在有5个轮询,4个进程会交替进行
Python的GIL锁
实现python解析器引入的概念,当线程执行过程中遇到IO阻塞,会主动释放GIL锁
CPU密集型:消耗CPU资源进行计算,如果此条件下处理多线程,资源来回切换会使得效率很低
IO密集型:消耗磁盘,花在CPU上的时间较少,如果此条件下处理多线程,优势在于IO阻塞时会主动释放资源
同步:前端调用后端,后端是同步的,直到处理完成才会通知A
异步:前端调用后端,后端是异步的,后端会通知前端我收到请求了,然后再去处理,处理完成后再通知前端
阻塞:前端调用后端,后端是阻塞的,前端一直等待后端处理,不会去处理其他事情
非阻塞:前端调用后端,后端是非阻塞的,前端先去做其他事情,不会一直等着
上述同步/异步和阻塞/非阻塞的区别就是执行对象的不同, 同步/异步针对的是被执行者,阻塞/非阻塞针对的是调用者
IO在计算机中指Input/Output,也就是输入和输出
计算机的组成:输入设备 (鼠标,键盘) + 分存储器(内存)+ CPU + 输出设备(显示器)
CPU把数据写入磁盘,磁盘的处理速度远不如CPU
- IO同步:CPU等待磁盘处理完后采取处理其他的程序
- IO异步:CPU不等待直接去处理后续程序