【发布时间】:2011-01-26 07:06:11
【问题描述】:
我正在 Linux 上运行一个应用程序 foo。在 Bash 脚本/终端提示符下,我的应用程序使用以下命令运行多线程:
$ foo -config x.ini -threads 4 < inputfile
系统监视器和顶部报告 foo 平均大约 380% 的 CPU 负载(四核机器)。我在 Python 2.6x 中重新创建了这个功能:
proc = subprocess.Popen("foo -config x.ini -threads 4", \
shell=True, stdin=subprocess.PIPE, \
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
mylist = ['this','is','my','test','app','.']
for line in mylist:
txterr = ''
proc.stdin.write(line.strip()+'\n')
while not proc.poll() and not txterr.count('Finished'):
txterr += subproc.stderr.readline()
print proc.stdout.readline().strip(),
Foo 运行速度较慢,top 报告 CPU 负载为 100%。 Foo 在 shell=False 时也能正常运行,但仍然很慢:
proc = subprocess.Popen("foo -config x.ini -threads 4".split(), \
shell=False, stdin=subprocess.PIPE, \
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
有没有办法让 Python 子进程不断填充所有线程?
【问题讨论】:
-
您是否尝试过使用 python 代码实际启动一个新线程,并在该新线程中执行 subprocess.Popen?
-
not txterr.count('Finished')确保进程一次不能处理多个输入行。是你想要的吗? -
@塞巴斯蒂安。我想让 foo 一直忙于所有四个线程。下面的 sarnold 之间的交换显示 foo 确实在运行 4 个线程,但每个线程只运行 25% 的负载。使用 Bash 将行连接到 foo 比 Python 循环更有效。foo 的输出非常结构化,带有 stderr 上的状态消息。输出仅在 stderr 报告“完成”后出现在 stdout 上。如果我不检索 stderr 缓冲区,整个过程会在大约 20-30 行处理后停止。
-
这不是 Python 循环效率的问题。在 stderr 中遇到
'Finished'之前,您不会向foo进程写入任何内容。为了避免由于操作系统管道缓冲区填满而导致的死锁,请使用proc.communicate()或使用我的回答中的线程stackoverflow.com/questions/4802119/…
标签: python multithreading subprocess