如何同步Python子进程的输出
我觉得我在同时运行两个Popen时遇到了同步输出的问题。看起来这两个不同命令的输出混在了一起。我还尝试使用RLock来防止这种情况发生,但没有成功。
一个示例输出可能是:
cmd1
cmd1
cmd2
cmd2
cmd2
cmd2
cmd1
cmd2
代码如下:
import subprocess
import threading
class PopenWorkerThread(threading.Thread):
def __init__(self, cmdLine):
self.lock = threading.RLock()
self.WebSphereCmdLine = cmdLine
threading.Thread.__init__(self)
def run(self):
logger.error('Runninf: ' + self.WebSphereCmdLine)
proc = subprocess.Popen(self.WebSphereCmdLine, shell=False, stdout=subprocess.PIPE)
while True:
self.lock.acquire()
print proc.stdout.readline()
self.lock.release()
def launch():
commandLine = ['ls -l', 'netstat']
for cmdLine in commandLine:
workerThread = PopenWorkerThread(cmdLine)
workerThread.start()
launch()
有没有办法让输出同步,这样看起来就像这样?
cmd1
cmd1
cmd1
cmd1
cmd1
cmd2
cmd2
cmd2
cmd2
cmd2
2 个回答
1
你现在是按行来锁定的,所以一个线程的行和另一个线程的行会交替出现。只要你愿意等到一个进程结束后再显示它的输出,你就可以用更大的“进程”粒度来锁定。当然,你必须在两个线程中使用同一个锁——如果每个线程都用一个完全不同的锁,就像你现在这样,显然是无法实现任何效果的。
所以,举个例子:
import subprocess
import threading
class PopenWorkerThread(threading.Thread):
lock = threading.RLock() # per-class, NOT per-instance!
def __init__(self, cmdLine):
self.WebSphereCmdLine = cmdLine
threading.Thread.__init__(self)
def run(self):
logger.error('Runninf: ' + self.WebSphereCmdLine)
proc = subprocess.Popen(self.WebSphereCmdLine, shell=False, stdout=subprocess.PIPE)
result, _ = proc.communicate()
with self.lock:
print result,
def launch():
commandLine = ['ls -l', 'netstat']
for cmdLine in commandLine:
workerThread = PopenWorkerThread(cmdLine)
workerThread.start()
launch()
1