什么可能导致我的工作线程Queue.get()延迟?

时间:2011-08-24 04:58:43

标签: python multithreading event-handling queue matplotlib

注意:这与我的其他主题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

1 个答案:

答案 0 :(得分:1)

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

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

在交互式会话中,通过启用交互模式也可以避免此问题:

import matplotlib.pyplot as plt
plt.ion()