1、从操做系统角度 操做系统处理任务, 调度单位是 进程 和 线程 。程序员
1.进程: 表示一个程序的执行活动 (打开程序、读写程序数据、关闭程序)数据库
2.线程: 执行某个程序时, 该进程调度的最小执行单位 (执行功能1,执行功能2) 一个程序至少有一个进程 一个进程至少有一个线程安全
1.并行: 须要处理的任务数 == CPU核心数量 两个任务 两个核心 任务1:------------- 任务2:-------------网络
2.并发: 须要处理的任务数 > CPU核心数量 三个任务 一个核心 任务1: ----- ------ 任务2: ------ 任务3: ------多线程
2、从程序角度 多进程和多线程 表示:当前程序能够同时执行多个任务 进程和线程都是由 操做系统调度完成并发
1.进程:socket
每一个进程都是有本身独立的内存空间,不一样进程之间的内存空间是不能共享。 不一样进程之间的通讯是由操做系统来完成的。 不一样进程之间的通讯效率低切换开销也大。函数
2.线程:spa
一个进程下能够有多个线程,同一个进程内的线程能够共享内存空间. 不一样线程之间的通讯 有进程 管理。 不一样线程之间的通讯效率高,切换开销小。操作系统
3.互斥锁:
共享意味着多个线程的竞争 会致使不安全问题。 为了保护内存空间的数据不被多个线程同时读写, 致使数据隐患, 因而诞生了" 互斥锁 "。 "互斥锁": 一种安全有序的让多个线程访问进程内存空间的机制。 当一个线程在访问进程内存空间时, 互斥锁能够防止其余线程访问 解释型语言:执行程序时,解释器按行执行程序内容,执行时检查问题。 编译型语言:经过编译器将程序编译为一个可执行文件,执行前检查问题。
3、Python中的多线程: GIL(全局解释器锁): 同一时刻只能有一个线程在运行。
坏处: 多线程不能充分利用多核CPU资源。
好处: 从根本上杜绝了多线程访问内存空间的安全问题。Python的多线程不适合并行, 但很是适合并发。 Python的多线程在遇到 IO阻塞函数执行, 会自动释放GIL, 让后面的线程执行任务。 若是没有 IO 操做, 那么解释器会每隔100次操做后, 强制释放GIL,让后面的线程执行。 import sys sys.getcheckinterval()
1.多进程:
适用于密集CPU任务, 能够充分调度CPU资源(大量的并行运算)。 multiprocessing 缺点:不适用于须要大量数据通讯和屡次切换的场景,由于进程之间通讯和切换成本高。
2.多线程:
适用于密集IO任务(网络IO,磁盘IO,数据库IO), 在IO阻塞时能够切换线程执行。 threading.Thread、multiprocessing.dummy
缺点:同一个CPU时间片只能执行一个任务,不能作到并行,只能作到并发。优势:线程之间切换和通讯很是方便,开销小。
3.协程:
由程序员自行编写调度功能, 切换协程就比如切换一个函数, 几乎没有切换开销。
特色是在单线程上执行多个任务, 调度由程序员控制,不通过操做系统, 因此没有进程线程的切换开销, 也不须要处理锁。
gevent monkey.patch_all() monkey的做用是将Python底层的网络库socket、select自动打个补丁, 程序在遇到网络IO阻塞时, 能够自动切换协程工做。
(该补丁不适用于本地IO)
优势:协程任务是基于用户的,不通过操做系统,执行效率极高。 缺点:单线程执行,不能处理 CPU密集任务,和密集本地IO任务。