使用 class 监控数据流并在 python 中以不同的时间间隔将报告打印到两个不同的 windows
Use a class to monitor a data stream and print reports to two different windows at different time intervals in python
我从来没有太多机会使用线程,但我正在从事的项目需要它。对于下面给出的示例,我已经大大简化了我的问题,但我很确定解决更简单问题的方法将帮助我解决更复杂的问题。
也就是说,这是我的缩减案例:我有一个 class,它的工作是监视通过 class 方法访问的传入数据流。我正在计算流中的统计数据。我想将有关传入数据的报告打印到一个终端 window 并以较短的时间间隔打印,并以固定(更长)的时间间隔将摘要报告打印到另一个 window。
下面的这个演示生成数据并将报告打印到同一个 window:我将如何修改它以将单独的报告打印到两个不同的 windows?
from __future__ import division
from random import gauss
import time
class MyStreamMonitor(object):
def __init__(self):
self.sum = 0
self.count = 0
@property
def mu(self):
return outv = self.sum/self.count
def generate_values(self):
while True:
yield gauss(0,1)
def monitor(self, report_interval=1):
start1 = time.time()
start2 = time.time()
for x in self.generate_values():
self.sum += x
self.count += 1
# print this to terminal 1
if time.time() - start1 > report_interval:
start1 = time.time()
print self.count, x
# print this to terminal 2
if time.time() - start2 > 5*report_interval:
start2 = time.time()
print self.mu
if __name__ == '__main__':
stream = MyStreamMonitor()
stream.monitor()
一种方法是写入一个文本文件,然后在第二个终端中,尾随文件:
def monitor(self, report_interval=1):
second = open('report.txt', 'wt')
start1 = time.time()
start2 = time.time()
for x in self.generate_values():
self.sum += x
self.count += 1
# print this to terminal 1
if time.time() - start1 > report_interval:
start1 = time.time()
print self.count, x
second.write('%d, %s\n' % (self.count, x))
# print this to terminal 2
if time.time() - start2 > 5*report_interval:
start2 = time.time()
print self.mu
second.write('%s\n', self.mu)
second.flush()
然后在第二个终端上:
$ tail -f report.txt
我最终采纳了@reptilicus 的建议,并使用 redis 将其构建为 client/server 应用程序。这是一个最低限度的工作示例:
server.py
from __future__ import division
from random import gauss
import time
import redis
class MyStreamMonitor(object):
def __init__(self):
self.sum = 0
self.count = 0
self.r = redis.StrictRedis()
@property
def mu(self):
if self.count >1:
outv = self.sum/self.count
else:
outv = 0
return outv
def generate_values(self):
while True:
yield gauss(0,1)
def monitor(self):
for x in self.generate_values():
self.sum += x
self.count += 1
# This is the magic here
self.r.publish('count', self.count)
self.r.publish('mu', self.mu)
if __name__ == '__main__':
stream = MyStreamMonitor()
stream.monitor()
listener.py
import redis
import time
import sys
r = redis.StrictRedis()
channel = sys.argv[1]
interval = float(sys.argv[2])
while True:
# Resubscribe at each iteration to ensure we are only receiving
# the newest message
pubsub = r.pubsub()
pubsub.subscribe(channel)
_ = pubsub.listen().next() # the first message is always just a "1"
message = pubsub.listen().next()
print message['data']
time.sleep(interval )
服务器将数据发布到 "count" 和 "mu" 频道。所以要运行这个,首先我们需要打开一个终端并启动服务器:
$ python server.py
然后我们可以为每个要收听的频道打开一个单独的终端,传入我们要收听的频道和睡眠间隔作为参数。
第一航站楼:
$ python listener.py mu 1
第二航站楼:
$ python listener.py count 2
郑重声明:安装 redis 非常轻松,根本不需要任何配置。根据您的需要,installation/configuration 可能更复杂,但至少对于这个玩具示例,我不需要做任何花哨的事情。
我从来没有太多机会使用线程,但我正在从事的项目需要它。对于下面给出的示例,我已经大大简化了我的问题,但我很确定解决更简单问题的方法将帮助我解决更复杂的问题。
也就是说,这是我的缩减案例:我有一个 class,它的工作是监视通过 class 方法访问的传入数据流。我正在计算流中的统计数据。我想将有关传入数据的报告打印到一个终端 window 并以较短的时间间隔打印,并以固定(更长)的时间间隔将摘要报告打印到另一个 window。
下面的这个演示生成数据并将报告打印到同一个 window:我将如何修改它以将单独的报告打印到两个不同的 windows?
from __future__ import division
from random import gauss
import time
class MyStreamMonitor(object):
def __init__(self):
self.sum = 0
self.count = 0
@property
def mu(self):
return outv = self.sum/self.count
def generate_values(self):
while True:
yield gauss(0,1)
def monitor(self, report_interval=1):
start1 = time.time()
start2 = time.time()
for x in self.generate_values():
self.sum += x
self.count += 1
# print this to terminal 1
if time.time() - start1 > report_interval:
start1 = time.time()
print self.count, x
# print this to terminal 2
if time.time() - start2 > 5*report_interval:
start2 = time.time()
print self.mu
if __name__ == '__main__':
stream = MyStreamMonitor()
stream.monitor()
一种方法是写入一个文本文件,然后在第二个终端中,尾随文件:
def monitor(self, report_interval=1):
second = open('report.txt', 'wt')
start1 = time.time()
start2 = time.time()
for x in self.generate_values():
self.sum += x
self.count += 1
# print this to terminal 1
if time.time() - start1 > report_interval:
start1 = time.time()
print self.count, x
second.write('%d, %s\n' % (self.count, x))
# print this to terminal 2
if time.time() - start2 > 5*report_interval:
start2 = time.time()
print self.mu
second.write('%s\n', self.mu)
second.flush()
然后在第二个终端上:
$ tail -f report.txt
我最终采纳了@reptilicus 的建议,并使用 redis 将其构建为 client/server 应用程序。这是一个最低限度的工作示例:
server.py
from __future__ import division
from random import gauss
import time
import redis
class MyStreamMonitor(object):
def __init__(self):
self.sum = 0
self.count = 0
self.r = redis.StrictRedis()
@property
def mu(self):
if self.count >1:
outv = self.sum/self.count
else:
outv = 0
return outv
def generate_values(self):
while True:
yield gauss(0,1)
def monitor(self):
for x in self.generate_values():
self.sum += x
self.count += 1
# This is the magic here
self.r.publish('count', self.count)
self.r.publish('mu', self.mu)
if __name__ == '__main__':
stream = MyStreamMonitor()
stream.monitor()
listener.py
import redis
import time
import sys
r = redis.StrictRedis()
channel = sys.argv[1]
interval = float(sys.argv[2])
while True:
# Resubscribe at each iteration to ensure we are only receiving
# the newest message
pubsub = r.pubsub()
pubsub.subscribe(channel)
_ = pubsub.listen().next() # the first message is always just a "1"
message = pubsub.listen().next()
print message['data']
time.sleep(interval )
服务器将数据发布到 "count" 和 "mu" 频道。所以要运行这个,首先我们需要打开一个终端并启动服务器:
$ python server.py
然后我们可以为每个要收听的频道打开一个单独的终端,传入我们要收听的频道和睡眠间隔作为参数。
第一航站楼:
$ python listener.py mu 1
第二航站楼:
$ python listener.py count 2
郑重声明:安装 redis 非常轻松,根本不需要任何配置。根据您的需要,installation/configuration 可能更复杂,但至少对于这个玩具示例,我不需要做任何花哨的事情。