Python 多线程

assastor 2020-01-23

1 线程与进程

进程:简单来说一个运行着的应用程序就是一个进程,一个进程中至少有一条线程,进程是资源分配的最小单位

线程:是进程的一个执行单元,线程是 CPU 调度的最小单位。

线程5 种状态: 新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead)

Python 中的线程与进程

Python 提供了 _thread(Python3 之前名为 thread ) 和 threading 两个线程模块。_thread 是低级、原始的模块,threading 是高级模块,对 _thread 进行了封装,增强了其功能与易用性,绝大多数时候,我们只需使用 threading 模块即可。

Python 提供了 multiprocessing 模块对多进程进行支持,它使用了与 threading 模块相似的 API 产生进程,除此之外,还增加了新的 API,用于支持跨多个输入值并行化函数的执行及跨进程分配输入数据,

2. GIL 相关概念

GIL 全称 Global Interpreter Lock(全局解释器锁),是 Python 解释器 CPython 采用的一种机制,通过该机制来控制同一时刻只有一条线程执行 Python 字节码,其他线程处于等待状态.本质是一把全局互斥锁,将并行运行变成串行运行。

CPython 下多线程的低效问题的解决方案:

1)使用无 GIL 机制的解释器;如:Jython 与 IronPython,但使用这两个解释器失去了利用 C 语言模块一些优秀特性的机会,因此这种方式还是比较小众。

2)使用 multiprocess 代替 threading;multiprocess 使用了与 threading 模块相似的 API 产生进程,不同之处是它使用了多进程而不是多线程,每个进程有自己独立的 GIL,因此不会出现进程之间的 GIL 争抢,但这种方式只对计算密集型任务有效,

3 多线程实现

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()

 4 多进程实现

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 下的测试结果我们发现:多线程效率优于多进程,单线程与多线程效率接近。

相关推荐