使用类监视数据流,并在python中以不同的时间间隔将报告打印到两个不同的窗口
我从来没有太多的机会玩线程,但我需要它的一个项目,我的工作。对于下面的例子,我已经大大简化了我的问题,但我非常确信,解决更简单问题的方法将使我获得解决更复杂问题的大部分方法 这就是说,这里是我的简化案例:我有一个类,它的工作是监视通过类方法访问的传入数据流。我正在从数据流中计算统计数据。我想在一个终端窗口和短时间间隔打印一份关于传入数据的报告,并定期(更长)在另一个窗口打印一份摘要报告 下面的演示将生成数据并将报告打印到同一个窗口:我将如何修改此操作以将单独的报告打印到两个不同的窗口使用类监视数据流,并在python中以不同的时间间隔将报告打印到两个不同的窗口,python,multithreading,python-2.7,stream,network-programming,Python,Multithreading,Python 2.7,Stream,Network Programming,我从来没有太多的机会玩线程,但我需要它的一个项目,我的工作。对于下面的例子,我已经大大简化了我的问题,但我非常确信,解决更简单问题的方法将使我获得解决更复杂问题的大部分方法 这就是说,这里是我的简化案例:我有一个类,它的工作是监视通过类方法访问的传入数据流。我正在从数据流中计算统计数据。我想在一个终端窗口和短时间间隔打印一份关于传入数据的报告,并定期(更长)在另一个窗口打印一份摘要报告 下面的演示将生成数据并将报告打印到同一个窗口:我将如何修改此操作以将单独的报告打印到两个不同的窗口 from
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
$ python listener.py mu 1
$ python listener.py count 2
我最终接受了@爬行动物”的建议,并用redis构建了一个客户机/服务器应用程序。下面是一个最低限度的工作示例: 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()
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 )
listener.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()
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 )
服务器将数据发布到“计数”和“mu”通道。因此,要运行此功能,首先我们需要打开一个终端并启动服务器:
$ python server.py
然后,我们可以为每个要收听的频道打开一个单独的终端,将要收听的频道和睡眠间隔作为参数传入
第一航站楼:
$ tail -f report.txt
$ python listener.py mu 1
$ python listener.py count 2
第二终端:
$ tail -f report.txt
$ python listener.py mu 1
$ python listener.py count 2
作为记录:安装redis非常轻松,实际上根本不需要任何配置。根据您的需要,安装/配置可能更复杂,但至少对于这个玩具示例,我不需要做任何花哨的事情。可以使用rabbitmq或类似的东西,并将其设置为客户机/服务器应用程序。监视器为数据提供服务器,客户机在特定的通道/队列上侦听他们需要的任何数据。或者可以使用常规套接字连接/gevent,在不同的端口上打开两个套接字,让客户机侦听。我喜欢您的一般方法,但以前从未使用过套接字(没有类似flask的框架)。你能给我看一个简单的工作示例或指导我学习教程吗?是使用gevent的echo服务器的一个例子。您使用的是什么操作系统?我想这是可行的,但感觉非常粗糙。此外,我还必须在每次写入之前截断文件。