Python:从不同的线程运行许多子进程很慢



我有一个程序,它有一个启动大量线程的进程。每个线程都可能使用子进程。Popen运行一些命令。我发现运行该命令的时间会随着线程数量的增加而增加。示例:

>>> def foo():
...     s = time.time()
...     subprocess.Popen('ip link show'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()
...     print(time.time() - s)
...
>>> foo()
0.028950929641723633
>>> [threading.Thread(target=foo).start() for _ in range(10)]
0.058995723724365234
0.07323050498962402
0.09158825874328613
0.11541390419006348 # !!!
0.08147192001342773
0.05238771438598633
0.0950784683227539
0.10175108909606934 # !!!
0.09703755378723145
0.06497764587402344

有没有另一种方法可以并行执行来自单个进程的大量命令,而不会降低性能?

Python的线程当然是并发的,但由于GIL的原因,它们并不是真正并行运行的。因此,它们不适合CPU绑定的应用程序。如果您需要真正并行化某些东西并允许它在所有CPU核心上运行,则需要使用多个进程。这里有一个很好的答案,可以更详细地讨论这个问题:线程和多处理模块之间有什么区别?。

对于上面的例子,multiprocessing.pool可能是一个不错的选择(注意,在这个模块中还有一个ThreadPool可用(。

from multiprocessing.pool import Pool
import subprocess
import time
def foo(*args):
s = time.time()
subprocess.Popen('ip link show'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()
return time.time() - s
if __name__ == "__main__":
with Pool(10) as p:
result = p.map(foo, range(10))
print(result)
# [0.018695592880249023, 0.009021520614624023, 0.01150059700012207, 0.02113938331604004, 0.014114856719970703, 0.01342153549194336, 0.011168956756591797, 0.014746427536010742, 0.013572454452514648, 0.008752584457397461]
result = p.map_async(foo, range(10))
print(result.get())
# [0.00636744499206543, 0.011589527130126953, 0.010645389556884766, 0.0070612430572509766, 0.013571739196777344, 0.009610414505004883, 0.007040739059448242, 0.010993719100952148, 0.012415409088134766, 0.0070383548736572266]

然而,如果您的函数与示例类似,因为它大多只是启动其他进程,而不进行大量计算——我怀疑并行化会有多大区别,因为子进程已经可以并行运行了。可能是因为所有这些进程导致整个系统暂时不堪重负(可能是CPU使用率很高,或者在短时间内尝试了过多的磁盘读/写(。我建议在运行程序时仔细查看系统资源(任务管理器等(。

也许这与python无关:打开一个新shell=打开一个文件,因为基本上所有东西都是linux 上的文件

使用以下命令查看打开文件的限制(默认值为1024(:

ulimit

并尝试用这个命令来提高它,看看你的代码是否变得更快:

ulimit -n 2048

相关内容

最新更新