最近因为工作需求,需要用下python,作为项目需求,多线程和多进程首先要考虑进去。在网上trace相关的一些资料,总是发现一些人在说:python下面是假线程。不觉得有点惊奇,据我所知,连java里面的线程对象(blue thread 虚拟机蓝色线程)也是跟系统有很大关系,多半内部包含了一个真实的系统线程对象,而python据官方说,并不是如同go一样是基于routine的,非真实线程 这种说法估计有误。。
于是乎,做试验:
代码段:
注明:该代码片断的外围还有4个线程执行该部分代码,故此工作线程远大于10个
直接spy 进程:
看见了吗,里面这么多工作线程。。。
linux系统,简单的把手上一个项目在linux上的trace结果发下:
看上图最上出现4个 worker2,简单点说就是一个 worker2主进程,并有3个其子进程(线程),上图最下
显示4个主进程,所以只有一个worker2。 综上,python里面的线程执行体就是真实的系统执行体
今天进一步研究下 python多线程/多进程机制 效率,不再阐述原理,一切‘坑’都产生于GIL机制, 直接上研究代码了:
import time
from threading import Thread
import multiprocessing
COUNT = 50000000
def countdown(n):
while n>0:
n -= 1
start = time.time()
countdown(COUNT)
end = time.time()
print('Single-trd Time taken in seconds -', end - start)
t1 = Thread(target=countdown, args=(COUNT/2,))
t2 = Thread(target=countdown, args=(COUNT/2,))
start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()
print('Multi-trd Time taken in seconds -', end - start)
t1 = multiprocessing.Process(target=countdown, args=(COUNT/2,))
t2 = multiprocessing.Process(target=countdown, args=(COUNT/2,))
start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()
print('Multi-process Time taken in seconds -', end - start)
window平台执行结果:
('Single-trd Time taken in seconds -', 1.5729999542236328)
('Multi-trd Time taken in seconds -', 4.871000051498413)
('Multi-process Time taken in seconds -', 6.109999895095825)
看到没有,完全没救了~~~
linux 平台执行结果:
(Single-trd Time taken in seconds -', 2.1106820106506348)
('Multi-trd Time taken in seconds -', 2.712383985519409)
('Multi-process Time taken in seconds -', 1.1155731678009033)
linux还好,可以看到 首先,使用多进程(多主进程)是没毛病,可以大大加快任务完成速度,多线程(子进程),还是慢一些,没有起到应有的作用。
结论: python下是真线程和真进程,但应用其上愚蠢的GIL机制,仅在linux下使用多进程,才可能得到 ‘并发’程序的好处。