assastor 2020-01-23
进程:简单来说一个运行着的应用程序就是一个进程,一个进程中至少有一条线程,进程是资源分配的最小单位
线程:是进程的一个执行单元,线程是 CPU 调度的最小单位。
线程5 种状态: 新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead)
Python 提供了 _thread(Python3 之前名为 thread ) 和 threading 两个线程模块。_thread 是低级、原始的模块,threading 是高级模块,对 _thread 进行了封装,增强了其功能与易用性,绝大多数时候,我们只需使用 threading 模块即可。
Python 提供了 multiprocessing 模块对多进程进行支持,它使用了与 threading 模块相似的 API 产生进程,除此之外,还增加了新的 API,用于支持跨多个输入值并行化函数的执行及跨进程分配输入数据,
GIL 全称 Global Interpreter Lock(全局解释器锁),是 Python 解释器 CPython 采用的一种机制,通过该机制来控制同一时刻只有一条线程执行 Python 字节码,其他线程处于等待状态.本质是一把全局互斥锁,将并行运行变成串行运行。
CPython 下多线程的低效问题的解决方案:
1)使用无 GIL 机制的解释器;如:Jython 与 IronPython,但使用这两个解释器失去了利用 C 语言模块一些优秀特性的机会,因此这种方式还是比较小众。
2)使用 multiprocess 代替 threading;multiprocess 使用了与 threading 模块相似的 API 产生进程,不同之处是它使用了多进程而不是多线程,每个进程有自己独立的 GIL,因此不会出现进程之间的 GIL 争抢,但这种方式只对计算密集型任务有效,
from threading import Thread # method 为线程要执行的具体方法 p1 = Thread(target=method) p2 = Thread(target=method) 需要实现更多条的线程也是一个道理。线程创建好了,通过 start 方法启动即可,示例如下: p1.start() p2.start() 如果是多线程任务,我们可能需要等待所有线程执行完成再进行下一步操作,使用 join 方法即可。示例如下: # 等待线程 p1、p2 都执行完 p1.join() p2.join()
from multiprocessing import Process # 创建两个进程实例:p1、p2,method 是要执行的具体方法 p1 = Process(target=method) p2 = Process(target=method) # 启动两个进程 p1.start() p2.start() # 等待进程 p1、p2 都执行完 p1.join() p2.join()
计算密集型任务:CPython 下执行计算密集型任务时,多进程效率最优,多线程还不如单线程。
I/O 密集型任务在 CPython 下的测试结果我们发现:多线程效率优于多进程,单线程与多线程效率接近。