主脚本是script.py
,我在启动script.py
时运行两个子进程,如下所示:
#PART ONE:
import subprocess
command = ["python", "first.py"]
command2 = ["python", "second.py"]
n = 5
for i in range(n):
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p2 = subprocess.Popen(command2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#PART TWO:
while True: #or while p.returncode==None:
output = p.stdout.readline().strip()
print output
if output == 'stop':
print 'success'
p.terminate()
p2.terminate()
break
所以基本上我在子进程p
打印'stop'时都停止了。一切都很好。我试图通过将'xterm','-e'
分别添加到command
和command2
来实现同样的工作,不同的是在单独的终端中启动两个子进程。问题现在是p.stdout.readline().strip()
我无法访问p
打印的内容,因此我无法停止主脚本script.py
中的子进程。我应该如何修改我的代码(特别是#PART TWO)以便使用command = ['xterm','-e','python','first.py']
我仍然可以读取输出并在打印'stop'时终止它们?
所以基本上#PART ONE现在是:
#PART ONE:
import subprocess
command = ["xterm","-e","python", "first.py"]
command2 = ["xterm","-e","python", "second.py"]
n = 5
for i in range(n):
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p2 = subprocess.Popen(command2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
问题是如何修改#PART TWO,以便可以读取输出,并在某些条件下终止进程。
答案 0 :(得分:0)
一个简单的解决方案是将first.py的stdout重定向到临时文件。然后修改part2以从该文件中读取而不是stdout的管道。
或者,xterm手册页可能会提供一些信息。
答案 1 :(得分:0)
老实说,我不记得我把它放在一起的来源,但是我使用下面的类或者一些修改后的版本来做你所说的。据我所知,子进程模块不允许条件终止,除非你把进程放在一个线程中。同时管理线程和进程的最简单方法是将它们捆绑为一个类。
import os,subprocess,threading
class RunSubprocess(object):
def __init__(self, cmd):
self.cmd = cmd
self.process = None
self.stdOut,self.stdErr = None,None
def run(self,timeout=100):
def target():
self.process = subprocess.Popen(self.cmd,
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
universal_newlines=True,
bufsize=4096)
self.stdOut, self.stdErr = self.process.communicate()
self.thread = threading.Thread(target=target)
self.thread.start()
## wait
if timeout != None:
self.thread.join(timeout)
if self.thread.is_alive():
print('The subprocess was auto-terminated due to timeout')
print("..."+self.process.poll())
self.process.terminate()
self.thread.join()
return self.process.returncode
return None
def terminate(self):
if self.thread.is_alive():
self.process.terminate()
self.thread.join()
if __name__ == '__main__':
cmd = "echo '...started'; sleep 2; echo '... finished'"
myProcess = RunSubprocess(cmd)
returnCode = myProcess.run(timeout=10)
myProcess.terminate()
print(myProcess.stdOut)
所以我相信你可以修改这个类来启动两个脚本,并且可以紧密相连。