一, 从操作系统角度
操作系统处理任务,
调度单位是进程和线程.
1. 进程:
表示一个程序的执行活动
(打开程序, 读写程序数据, 关闭程序)
2. 线程:
执行某个程序时,
该进程调度的最小执行单位
(执行功能 1, 执行功能 2)
一个程序至少有一个进程
一个进程至少有一个线程
1. 并行:
需要处理的任务数 == CPU 核心数量
两个任务
两个核心
任务 1:-------------
任务 2:-------------
2. 并发:
需要处理的任务数 > CPU 核心数量
三个任务
一个核心
任务 1: ----- ------
任务 2: ------
任务 3: ------
二, 从程序角度
多进程和多线程
表示: 当前程序可以同时执行多个任务
进程和线程都是由
操作系统调度完成
1. 进程:
每个进程都是有自己独立的内存空间, 不同进程之间的内存空间是不能共享.
不同进程之间的通信是由操作系统来完成的.
不同进程之间的通信效率低切换开销也大.
2. 线程:
一个进程下可以有多个线程, 同一个进程内的线程可以共享内存空间.
不同线程之间的通信 有进程 管理.
不同线程之间的通信效率高, 切换开销小.
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
- <pre style="box-sizing: border-box; -webkit-tap-highlight-color: transparent; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: normal; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"> 缺点: 同一个 CPU 时间片只能执行一个任务, 不能做到并行, 只能做到并发. 优点: 线程之间切换和通信非常方便, 开销小.</pre>
3. 协程:
由程序员自行编写调度功能,
切换协程就好比切换一个函数,
几乎没有切换开销.
特点是在单线程上执行多个任务,
调度由程序员控制, 不经过操作系统,
所以没有进程线程的切换开销,
也不需要处理锁.
- gevent
- monkey.patch_all()
monkey 的作用是将 Python 底层的网络库 socket,select 自动打个补丁,
程序在遇到网络 IO 阻塞时,
可以自动切换协程工作.
该补丁不适用于本地 IO
<pre style="box-sizing: border-box; -webkit-tap-highlight-color: transparent; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: normal; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"> 优点: 协程任务是基于用户的, 不经过操作系统, 执行效率极高. 缺点: 单线程执行, 不能处理 CPU 密集任务, 和密集本地 IO 任务.</pre>
来源: http://www.jianshu.com/p/b64c81fda34b