Bob*_*ano 3 subprocess python-multithreading python-3.x
我有一个包含 1 个进程的程序,它启动了很多线程。每个线程可能使用 subprocess.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
Run Code Online (Sandbox Code Playgroud)
是否有另一种方法可以在不降低性能的情况下从单个进程并行执行大量命令?
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]
Run Code Online (Sandbox Code Playgroud)
但是,如果您的函数与示例类似,因为它主要只是启动其他进程并且不进行大量计算 - 我怀疑并行化它会产生很大的不同,因为子进程已经可以并行运行。速度变慢可能是因为您的整个系统因所有这些进程而暂时不堪重负(可能是 CPU 使用率过高或在短时间内尝试了过多的磁盘读/写)。我建议在运行程序时仔细查看系统资源(任务管理器等)。
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |