Python 的多线程受到 GIL(Global Interpreter Lock) 的限制,GIL 是一把加到了 Python 的解释器的锁,使得在任意时刻只允许一个 Python 进程使用 Python 解释器,也就是任意时刻,Python 只有一个线程在运行。
GIL 严重影响了计算密集型(CPU-bound) 的多线程程序,此时的多线程与单线程性能没什么差异,也发挥不了多核的威力。但对 I/O 密集型(I/O-bound) 影响不大,因为 CPU 多数时候是在等待。
为了突破 GIL 的 CPU 密集型程序的限制,可以使用非 CPython 解释器,如 Jython, IronPython 或 PyPy, 更为现实的做法就是使用子进程来替代线程去承担较为繁重的计算任务,因为 GIL 是加在进程上的,所以新的进程有独立的 GIL.
新建子进程来处理任务
需用到 multiprocessing.Process 类,这个类在 Python 2.6 就开始存在了。一般的编程语言创建一个进程是要去执行一个外部任命,然后获得它的输出,而 Python 可以像创建线程一样创建子进程,且欲执行的任务直接由 Python 在其中编写
from datetime import datetime
import time
from multiprocessing import Process
import os
def job(name):
for _ in range(3):
print('[Child {}][{}]'.format(os.getpid(), datetime.now()))
time.sleep(1)
print(f'sub process {os.getpid()} {name} done')
if __name__ == '__main__':
p = Process(target=job, args=('bob',)) # 留意如何向子进程传递参数
p.start()
print(f'main process {os.getpid()} done') # p.pid 可以得到子进程的 ID
p.join() # 如果不 join 的话,主进程一退出,子进程也随即结束
from datetime import datetime
import time
from multiprocessing import Process
import os
def job ( name ) :
for _ in range ( 3 ) :
print ( '[Child {}][{}]' . format ( os . getpid (