我试图运行一个运行另一个脚本(客户端)的python脚本(Activator),并在一定时间限制后终止它。 (本例中为5秒)。
激活
import random, sys, os, socket
import time, datetime
import subprocess
from threading import Thread
from multiprocessing import Queue
class deamon_pckg:
def __init__(self, msg_type, info, exeption=None):
self.msg_type = msg_type
self.info = info
self.exception = exeption
class Process_comm:
@staticmethod
def deamon(process, q):
while process.poll() is None:
out = process.stdout.readline().rstrip()
if out != '':
d_pckg = deamon_pckg('cmd', out)
q.put(d_pckg)
exit_code = process.returncode
if exit_code != 0:
err_msg = process.stderr.read()
else:
err_msg = None
d_pckg = deamon_pckg('EXIT', exit_code, err_msg)
q.put(d_pckg)
def __init__(self, process):
self.process = process
self.q = Queue()
self.d = Thread(target=Process_comm.deamon, args=(self.process, self.q))
self.d.start()
def close(self):
if self.process.returncode is None:
self.terminate()
self.d.join()
def terminate(self):
self.process.terminate()
def get(self, blocking=False):
if blocking:
return self.q.get()
else:
if self.q.empty():
return None
else:
return self.q.get()
if __name__ == '__main__':
print "Activator online"
start_time = datetime.datetime.now()
process = subprocess.Popen(['python', "C:\work\Router\src\demiborg.py"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
d = Process_comm(process)
while True:
delta = (datetime.datetime.now() - start_time)
dpckg = d.get()
if delta.seconds >= 5:
d.terminate()
break
if dpckg is None:
time.sleep(0.1)
else:
if dpckg.msg_type == 'EXIT':
print "[{}]\t{}".format(dpckg.msg_type, dpckg.info)
if dpckg.exception is not None:
print "{}".format(dpckg.exception)
break
else:
print "[{}]\t{}".format(dpckg.msg_type, dpckg.info)
d.close()

客户端:
import random, sys, os, socket
import time, datetime
def get_time_stamp():
ts = time.time()
st = datetime.datetime.fromtimestamp(ts).strftime('%f:%S:%M:%H:%d:%m:%Y')
return st
def put(fout,msg):
fout.write('[{:>30}]'.format(get_time_stamp()) + '\t' + msg + '\n')
fout.flush
print msg
if __name__ == '__main__':
fout = open('demiborg.txt','wb')
put(fout,"Start DemiBorg")
for i in range(20):
put(fout,"time - {}".format(i))
time.sleep(0.5)
put(fout,'End')
fout = open('ERROR', 'wb')
fout.close()

如果我跑
Activator online
[cmd] Start DemiBorg
[cmd] time - 0
[cmd] time - 1
[cmd] time - 2
[cmd] time - 3
[cmd] time - 4
[cmd] time - 5
[cmd] time - 6
[cmd] time - 7
[cmd] time - 8
[cmd] time - 9
Process finished with exit code 0

但是当我通过Windows控制台运行时,我根本没有输入(就像客户端没有运行)。
C:\work\Router\src>C:\work\Router\src\plygrnd_activator.py
Activator online
C:\work\Router\src>

更进一步,如果没有杀死客户端,我注意到所有消息仅在客户端完成运行后才作为一个块一起出现。为什么只使用pycharm它工作正常但在控制台上我没有得到实时反馈? 目的是在控制台上运行。 谢谢!
答案 0 :(得分:1)
解决方案,问题在于缓冲区大小。
而不是使用:
process = subprocess.Popen(['python', "C:\work\Router\src\demiborg.py"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

我已添加" -u" " python"之后的标志:
process = subprocess.Popen(['python','-u', "C:\work\Router\src\demiborg.py"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)