Python 如何处理大量线程?
# data is a list
Threading_list=[]
class myfunction(threading.Thread):
def __init__(self,val):
.......
.......
def run(self):
.......
.......
for i in range(100000):
t=myfunction(data[i]) # need to execute this function on every datapoint
t.start()
Threading_list.append(t)
for t in Threading_list:
t.join()
这段代码会创建大约100000个线程,但我最多只能创建32个线程。请问这个代码可以怎么改?
2 个回答
0
这里有一个例子,它可以计算一个任意长度列表中每个数字的平方,使用了32个线程,通过一个叫做 ThreadPoolExecutor 的工具。正如Ellioh所说,在某些情况下你可能不想使用线程,这时候你可以很方便地切换到 ProcessPoolExecutor。
import concurrent.futures
def my_function(x):
return 2**x
data = [1, 6, 9, 3, 8, 4, 213, 534]
with concurrent.futures.ThreadPoolExecutor(max_workers=32) as executor:
result = list(executor.map(my_function, data))
print(result)
4
在Python中,创建很多线程其实很少需要。更重要的是,我几乎想不出有什么理由需要这么做。其实有一些合适的设计模式可以解决并行执行代码的问题,这些模式会限制线程的数量。其中一个就是反应器模式。
你到底想做什么呢?
另外要记住,由于全局解释器锁(GIL)的存在,Python的线程在处理计算任务时并不会提升性能,即使是在多处理器和多内核的系统上(顺便说一句,真的会有100000个内核的系统吗?我对此表示怀疑。:))。唯一能提升性能的机会是,如果计算部分是在用C/C++编写的模块中执行,这些模块在工作时不需要获取GIL。通常,Python线程是用来并行执行包含阻塞I/O操作的代码。
更新:注意到有stackless-python标签。根据我所知,它支持微线程。不过,你到底想做什么还是不太清楚。
如果你只是想处理100000个值(对每个值应用一个公式?),那么最好写成这样:
def myfunction(val):
....
return something_calculated_from_val
results = [myfunction(d) for d in data] # you may use "map(myfunction, data)" instead
这样应该会好很多,除非myfunction()
执行了一些阻塞的I/O操作。如果有的话,ThreadPoolExecutor
可能真的会有帮助。