我希望让我的Python(2.7.5)脚本连续读取并解析来自连续子进程的时间戳和其他信息,对系统时间进行时间戳比较,并将其写入文本文件。我将通过EPICS频道访问过程调用camonitor实用程序。这类似于top这样的行为,它将持续运行并更新数据,直到进程被杀死为止。谷歌搜索并浏览了许多帖子后,这就是我的意思。我想我缺少将数据连续添加到文本文件的东西。
import subprocess
from Queue import Queue, Empty
from threading import Thread
from datetime import datetime
import time
class NonBlockingStreamReader:
def __init__(self, stream):
'''
stream: stream to read from such as stdout
'''
self._s = stream
self._q = Queue()
def _populateQueue(stream, queue):
'''
collect lines from 'stream' and put them in 'queue'
'''
while True:
line = stream.readline()
if line:
queue.put(line)
else:
raise UnexpectedEndOfStream
self._t = Thread(target = _populateQueue, args = (self._s, self._q))
self._t.daemon = True
self._t.start() # start collecting lines from thel stream
def readline(self, timeout = None):
try:
return self._q.get(block = timeout is not None, timeout = timeout)
except Empty:
return None
class UnexpectedEndOfStream(Exception): pass
def caMonitor(signalList):
cmd = ["camonitor"]
# add signals to the camonitor command
cmd.extend(signalList)
print(cmd)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
# wrap process.stdout with a NonBlockingStreamReader object:
nbsr = NonBlockingStreamReader(process.stdout)
# get the output for X seconds
t_end = time.time() + 1
fmt = "%H:%M:%S.%f"
while time.time() < t_end:
try:
output = nbsr.readline(0.05)
# 0.05 secs to get the results
'''
if not output:
print ('[No data]')
break
'''
signal = output[0:16]
timestamp = output[42:57]
now = datetime.now()
sysTime = now.strftime("%H:%M:%S.%f")
tstamp1 = datetime.strptime(timestamp, fmt)
tstamp2 = datetime.strptime(sysTime, fmt)
if tstamp1 > tstamp2:
td = tstamp1 - tstamp2
else:
td = tstamp2 - tstamp1
print(signal + ' ' + timestamp + ' systime ' + sysTime + ' delta: ' + str(td))
with open('camonlog.log', 'a+') as f:
f.write(signal + ' ' + timestamp + ' systime ' + sysTime + ' delta: ' + str(td) + '\n')
except TypeError:
print "no data"
答案 0 :(得分:0)
在类 NonBlockingStreamReader 中,如果流中没有任何数据,populateQueue方法将仅引发UnexpectedEndOfStream异常,并且该线程将终止并且不会监视您的流。
因此定义这样的方法:
def _populateQueue(stream, queue):
while True:
line = stream.readline()
if line:
queue.put(line)
else:
time.sleep(1)