我认为我在同步运行两个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
答案 0 :(得分:1)
你用一条线的粒度锁定,所以当然来自一个线程的线可以与另一个线的线交替。只要您愿意等到进程结束然后显示其任何输出,您就可以锁定更大的“进程”粒度。当然,你必须为两个线程使用SAME锁 - 让每个线程使用一个完全独立的锁,正如你现在所做的那样,显然无法实现任何目标。
所以,例如:
导入子流程 导入线程
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'] 对于commandLine中的cmdLine: workerThread = PopenWorkerThread(cmdLine) workerThread.start()
发射()
答案 1 :(得分:0)