我发现在使用threading.Thread类时,如果我同时运行多个线程,则每个线程的执行速度会变慢。这是一个小样本程序,用于演示这一点。
如果我用1个线程运行它,每次迭代在我的计算机上大约需要半秒钟。如果我用4个线程运行它,每次迭代大约需要4秒。
我是否遗漏了子类化threading.Thread对象的一些关键部分?
提前致谢
import sys
import os
import time
from threading import Thread
class LoaderThread(Thread):
def __init__(self):
super(LoaderThread,self).__init__()
self.daemon = True
self.start()
def run(self):
while True:
tic = time.time()
x = 0
for i in range(int(1e7)):
x += 1
print 'took %f sec' % (time.time()-tic)
class Test(object):
def __init__(self, n_threads):
self.n_threads = n_threads
# kick off threads
self.threads = []
for i in range(self.n_threads):
self.threads.append(LoaderThread())
if __name__ == '__main__':
print 'With %d thread(s)' % int(sys.argv[1])
test = Test(int(sys.argv[1]))
time.sleep(10)
答案 0 :(得分:1)
那是因为CPython实际上并没有同时进行线程化; CPython只允许一次运行一个Python代码线程:即
线程1运行,没有其他线程运行... 线程2运行,没有其他线程运行。
此行为是因为Global Interpreter Lock但是,在IO期间,GIL被释放,允许IO绑定进程同时运行。
答案 1 :(得分:1)
在CPython中,由于GIL,一次只能执行一行python。
GIL仅对CPU绑定进程有用。 IO绑定流程仍然可以从线程中获益(因为GIL已经发布)。由于您的程序在python代码中“忙”循环,因此您在此处看不到线程的任何性能优势。
请注意,这是一个CPython(实现)细节,严格来说并不是语言 python 本身的一部分。例如,Jython和IronPython没有GIL,可以拥有真正的并发线程。
如果你想在CPython中获得更好的并发性,请查看multiprocessing
模块而不是threading
。