从多处理过程更新散景图

时间:2016-12-14 11:38:06

标签: python multiprocessing bokeh

我正在使用Bokeh服务器绘制来自传感器的在线数据。我编写了一个multiprocessing.Process子类,它从传感器读取数据,然后通过管道将其提供给另一个子类,该子类应该使用传入的数据更新Bokeh图。

如何从管道中异步读取绘图Process并将其绘制到Bokeh?

考虑Grapher类,假设另一个进程已经将数据发送到input_pipe

from multiprocessing import Process

from bokeh.client import push_session
from bokeh.models import ColumnDataSource
from bokeh.plotting import curdoc, figure

from functools import partial

class Grapher(Process):
  def __init__(self, name, input_pipe):
    super(Grapher, self).__init__(name=name, daemon=True)
    self.input_pipe = input_pipe

    self.doc = curdoc()
    self.source = ColumnDataSource(dict(time=[], value=[])
    self.fig = figure()
    self.fig.line(source=self.source, x='time', y='value')
    self.doc.add_root(self.fig)
    self.session = push_session(self.doc)  # To keep session updated.

  def run(self):
    while True:
      time, value = self.input_pipe.recv()
      self.doc.add_next_tick_callback(partial(self.update, time, value))

  @gen.coroutine
  def update(self, time, value):
    self.source.stream(dict(time=[time], value=[value]))

这里的代码是从Bokeh文档中的example中采用的。另外,我运行bokeh serve,以便curdoc()可以连接到某些内容。从Bokeh服务器日志中,我看到连接就在那里。

然而,问题似乎是updatewhile循环的下一个滴答之后并没有真正执行。我可以通过在update中添加一条永远不会打印出来的日志消息来检查它。

如果我尝试将add_next_tick_callback更改为仅update调用,则该函数确实已运行,但会话不会绘制任何内容。

这会导致什么问题?代码看起来很合理,我找不到使用这种方法失败的文档。

感谢。

1 个答案:

答案 0 :(得分:1)

对应用程序使用bokeh.client方法时,如果要对事件进行处理,并在发生事件时调用回调,则必须在结束时调用阻塞函数session.loop_until_closed()。这就是为什么能够监控事件并调用回调,实际上是为了监控事件和调用回调。

如果调用阻止功能有问题,并且您不想使用bokeh serve app.py样式的应用,那么您可以尝试在另一个线程中调用session.loop_until_closed()(不是100%这将会工作),或者开始你自己的Tornado ioloop并直接寄回一个Bokeh服务器应用程序。在即将发布的0.12.4版本中,该技术将得到更好的展示,但您现在可能会发现此笔记本是一个有用的参考:

https://gist.github.com/bryevdv/ff84871fcd843aceea4f0197be9c57e0

请注意,该笔记本是一个概念验证,您需要0.12.4开发版才能使用它,并且一些使用细节可能会发生变化。