python多进程和多线程

来源:互联网 发布:mysql解压版安装配置 编辑:程序博客网 时间:2024/05/18 21:07

注:本文reference

首先使用python的多进程和多线程来完成一个简单的任务,做一个直观的对比:往一个数组中疯狂放值。
1. 简单玩法(单线程)

import timenb_repeat = 50def a_complex_operation(*args):    a = []    for x in range(999999):        a.append(x)    return Nonet1 = time.time()for _ in range(nb_repeat):    a_complex_operation()print time.time()-t1

耗时4.82s

2.多进程版本

from multiprocessing import Poolnb_repeat = 50def a_complex_operation(*args):    a = []    for x in range(999999):        a.append(x)    return Nonepool = Pool(processes=nb_repeat)results = pool.map(a_complex_operation, [None for _ in range(nb_repeat)])

耗时 2.74s

3.多线程玩法

from threading import Threadimport timenb_repeat = 50def a_complex_operation(*args):    a = []    for x in range(999999):        a.append(x)    return Nonet1 = time.time()threads = []for _ in range(nb_repeat):    threads.append(Thread(target=a_complex_operation))[x.start() for x in threads][x.join() for x in threads]print time.time()-t1

耗时14.088s。

岂有此理!!!,怎么回事?
说到为什么使用多线程反而耗时会更久,就不得不提GIL, Global Interpreter Lock.
GIL全局解释器锁是编程语言中的一种控制线程同步的机制。在同一时刻,即使机器有多核cpu,GIL只允许一个线程运行,用来避免多个线程共享非线程安全的代码片。python使用的CPython解释器和ruby使用MRI解释器都使用了GIL机制。
由于上面代码执行的属于计算密集型(cpu bound)任务,加之GIL的控制,导致多线程性能下降。而多进程(multiprocessing)充分利用了多核cpu。因为多个进程可以同时(同一时刻)运行在多个cpu上,达到真正的并行。每个进程都有单独的GIL。

那是不是说python中multiprocessing就所有的场景里都是最好的终极方案呢?
答案肯定不是。上面已经说到在计算密集型(cpu bound)任务中,python多线程是低效的。但是在处理网络任务这种io密集型任务的场景中,python多线程还是很有优势的。1)首先,从操作系统原理上分析,线程肯定比进程轻量。2)在多线程执行io任务时,每个线程的大部分时间是在等待io,所以GIL控制所带来的影响可以忽略不计。

0 0