使用subprocess.Popen会产生不完整的结果,而作为subprocess.call则会给出正确的输出
这与一个包含6个作业的回归脚本有关,每个作业执行相同的任务,但是在不同的输入文件上。我正在使用SubProcess.Popen并行运行所有内容
使用Shell脚本执行任务,该脚本调用了许多C编译的可执行文件,其工作是生成一些文本报告,然后将文本报告信息转换为jpg图像
调用C编译可执行文件的shell脚本示例(runit是文件名)
#!/bin/csh -f
#file name : runit
#C - Executable 1
clean_spgs
#C - Executable 2
scrub_spgs_all file1
scrub_spgs_all file2
#C - Executable 3
scrub_pick file1 1000
scrub_pick file2 1000
在使用subprocess.Popen时,scrub_spgs_all和scrub_pick都试图并行运行,从而导致脚本生成不完整的结果,即输出文本文件不包含完整的信息,并且还缺少一些输出文本报告。
subprocess.Popen调用是
resrun_proc = subprocess.Popen("./"+runrescompare, shell=True, cwd=rescompare_dir, stdout=subprocess.PIPE, stderr=subprocess.POPT, universal_newlines=True)
其中runrescompare是一个shell脚本,并具有
#!/bin/csh
#some other text
./runit
使用subprocess.call可以正确生成所有输出文本文件和jpg图像,但是我不能并行运行所有6个作业。
resrun_proc = subprocess.call("./"+runrescompare, shell=True, cwd=rescompare_dir, stdout=subprocess.PIPE, stderr=subprocess.POPT, universal_newlines=True)
使用python子进程调用从shell脚本调用C可执行文件的正确方法是什么(其中所有6个作业都可以并行运行)(使用python 3.5.1?
谢谢。
您尝试使用subprocess.Popen()模拟多处理,该方法无法按您希望的那样工作:一段时间后除非您消耗了输出,否则输出将被阻塞,例如,使用communicate()
(但是这是阻塞的)或通过读取输出,但是有6个并发循环处理,势必会陷入僵局。
最好的方法是subprocess.call
在单独的线程中运行这些行。
有几种方法可以做到这一点。带锁的小简单示例:
import threading,time
lock=threading.Lock()
def func1(a,b,c):
lock.acquire()
print(a,b,c)
lock.release()
time.sleep(10)
tl=[]
t = threading.Thread(target=func1,args=[1,2,3])
t.start()
tl.append(t)
t=threading.Thread(target=func1,args=[4,5,6])
t.start()
tl.append(t)
# wait for all threads to complete (if you want to wait, else
# you can skip this loop)
for t in tl:
t.join()
我花时间创建了一个更适合您需求的示例:
2个线程执行一个命令并获取输出,然后在锁中打印该输出以避免混淆。我已经使用check_output
了此方法。我正在使用Windows,并且同时列出了C和D驱动器。
import threading,time,subprocess
lock=threading.Lock()
def func1(runrescompare,rescompare_dir):
resrun_proc = subprocess.check_output(runrescompare, shell=True, cwd=rescompare_dir, stderr=subprocess.PIPE, universal_newlines=True)
lock.acquire()
print(resrun_proc)
lock.release()
tl=[]
t=threading.Thread(target=func1,args=["ls","C:/"])
t.start()
tl.append(t)
t=threading.Thread(target=func1,args=["ls","D:/"])
t.start()
tl.append(t)
# wait for all threads to complete (if you want to wait, else
# you can skip this loop)
for t in tl:
t.join()
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句