【问题标题】:What can cause delay in my worker thread Queue.get()?什么会导致我的工作线程 Queue.get() 延迟?
【发布时间】:2011-08-24 04:58:43
【问题描述】:

注意:这与我的另一个主题herehere 密切相关,但是是一个独立的问题,如果您不感兴趣,则无需阅读它们。..

我在处理队列中的项目时遇到了一些意外延迟。它似乎与 matplotlib GUI 线程有关,因为我可以通过避免生成任何 GUI 事件来使延迟任意长,但例如如果我创建一些鼠标移动事件,我可以进入队列。造成这种延迟的原因是什么以及如何解决?

# ~/repo/wim/mpl_q.py
import threading, Queue, time, random, sys

t0 = time.time()
t = lambda : time.time() - t0

def worker():
  while True:
    thing = queue.get()
    sys.stdout.write('({0}) hello {1}!\n'.format(t(), thing))
    queue.task_done()

queue = Queue.Queue()
thread = threading.Thread(target=worker)
thread.daemon = True
thread.start()

def say_hello(thing='world'):
  print '({0}) --> say_hello({1})'.format(t(), thing)
  queue.put(thing)

say_hello('world')
say_hello('cruel world')
say_hello('stack overflow')

import matplotlib.pyplot as plt
fig = plt.figure()

def event_handler(event):
  world = random.choice(['foo', 'bar', 'baz'])
  say_hello(world)

event_handler_ = lambda x: event_handler(x)
cid0 = fig.canvas.mpl_connect('key_press_event', event_handler)
cid1 = fig.canvas.mpl_connect('button_press_event', event_handler_)

plt.show()

典型输出示例,您可以看到脚本项目按时发生,但用户生成的项目可能会晚得多..

wim@wim-acer:~/repo/wim$ python mpl_q.py
(0.000166893005371) --> say_hello(world)
(0.000200986862183) --> say_hello(cruel world)
(0.000216960906982) hello world!
(0.000231027603149) --> say_hello(stack overflow)
(0.000247955322266) hello cruel world!
(0.00425505638123) hello stack overflow!
(7.80911588669) --> say_hello(foo)
(7.84842705727) hello foo!
(9.41998004913) --> say_hello(baz)
(11.4023530483) hello baz!
(14.3315930367) --> say_hello(foo)
(19.4317750931) hello foo!
(20.96124506) --> say_hello(bar)
(23.2277729511) --> say_hello(baz)
(23.2278220654) hello bar!
(29.0094120502) hello baz!

编辑:我正在使用GTKAgg 后端和matplotlib 1.1.0 版

【问题讨论】:

    标签: python multithreading event-handling queue matplotlib


    【解决方案1】:

    我真的不知道为什么,但是如果您在导入 pyplot 之前声明 matplotlib.use(backend),问题似乎就消失了:

    import matplotlib
    matplotlib.use('TkAgg')
    import matplotlib.pyplot as plt
    

    在交互式会话中,也可以通过打开交互模式来避免该问题:

    import matplotlib.pyplot as plt
    plt.ion()
    

    【讨论】:

    • 我也注意到了这一点,实际上是因为您对我的其他问题的回答.. :) 但是我不太喜欢 matplotlib.use 的解决方案,因为如果 matplotlib.pyplot 已经已在交互式会话中导入
    • @wim:在交互式会话中,请改用plt.ion()
    • plt.ion() 使plt.show() 非阻塞,但似乎对延迟问题没有任何影响
    • unutbu,你知道用GTKAgg后端解决问题的任何方法吗?
    • @wim:嗯。 plt.ion() 以某种方式为我解决了延迟问题。而且我也无法重现 GTKAgg 后端问题(尽管我最终遇到了不同的问题)。我仍在使用 matplotlib 0.99.0 版。也许这就是差异的原因......
    猜你喜欢
    • 2019-05-09
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 2020-03-04
    相关资源
    最近更新 更多