在中断Queue.get(timeout = 60)之后,在另一个线程成功完成Queue.put('something')之后,以下Queue.get()不会返回。为什么?

时间:2017-04-05 09:45:17

标签: python multithreading python-2.7 queue python-multithreading

我已经解决了这个问题,但我想知道自己做错了什么。 我创建了一个Queue.Queue()并错误地调用了get(timeout = 60)。队列为空,因此呼叫被阻止。我用CTRL-C打断了它。我实例化了一个辅助线程。在睡眠之后,它会填充队列。当辅助线程正在休眠时,我调用了get(),它再次被阻止了。当辅助线程唤醒时,它填充队列,但主get()没有返回。为什么呢?

文件secondary.py:

import time, threading
class putter(threading.Thread):
    def __init__(self, q):
        super(putter, self).__init__()
        self.q = q
        self._keep_going = True
    def stop(self):
        self._keep_going = False
    def run(self):
        print('T2 sleeping to allow calling get')
        time.sleep(5)
        print('T2 awoke, putting')
        self.q.put('Hello world!')
        while self._keep_going:
            time.sleep(1)
            print('{} T2 running'.format(time.time()))
            print('qsize {}'.format(self.q.qsize()))

交互式口译员会议:

bruno@jeeg:/mnt/storage/src/foo$ python
Python 2.7.11+ (default, Apr 17 2016, 14:00:29) 
[GCC 5.3.1 20160413] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import Queue
>>> from secondary import putter
>>> queue = Queue.Queue()
>>> queue.get(timeout=60)
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/Queue.py", line 177, in get
    self.not_empty.wait(remaining)
  File "/usr/lib/python2.7/threading.py", line 359, in wait
    _sleep(delay)
KeyboardInterrupt
>>> p = putter(queue)
>>> p.start()
T2 sleeping to allow calling get

>>> queue.get()
T2 awoke, putting
1491384824.07 T2 running
qsize 1
1491384825.08 T2 running
qsize 1
1491384826.08 T2 running
qsize 1
1491384827.08 T2 running
[... forever]

另一个会话,测试@Himal

>>> p.start()
T2 sleeping to allow calling get
>>> queue.get(timeout=4)
T2 awoke, putting
1491401131.61 T2 running
qsize 1
1491401132.61 T2 running
qsize 1
'Hello world!'
>>> 1491401133.61 T2 running
qsize 0
1491401134.61 T2 running
qsize 0
[... T2 keeps running but now get(timeout=4) has returned and the queue is empty]

1 个答案:

答案 0 :(得分:0)

get()的调用已返回,但交互式解释器会话未返回。后者最有可能的原因是另一个线程仍在运行,但我并不是100%肯定。

尝试运行此程序:

import time, threading
class putter(threading.Thread):
    def __init__(self, q):
        super(putter, self).__init__()
        self.q = q
        self._keep_going = True
    def stop(self):
        self._keep_going = False
    def run(self):
        print('T2 sleeping to allow calling get')
        time.sleep(5)
        print('T2 awoke, putting')
        self.q.put('Hello world!')
        while self._keep_going:
            time.sleep(1)
            print('{} T2 running'.format(time.time()))
            print('qsize {}'.format(self.q.qsize()))

from Queue import Queue

q = Queue()

p = putter(q)
p.start()

q.get()

print("Get returned!")

这将正确打印以下输出:

T2 sleeping to allow calling get
T2 awoke, putting
Get returned!
1491386038.93 T2 running
qsize 0
1491386039.93 T2 running
qsize 0
1491386040.94 T2 running
qsize 0
...

当我在交互式解释器中运行以下代码时,输​​出正如预期的那样,命令甚至会返回(请参阅>>>之后的行中的Get returned!)。后者可能与您的结果不同,因为我们使用不同的操作系统。

Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:24:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from so_test import putter
>>> from Queue import Queue
>>> q = Queue()
>>> putter(q).start()
T2 sleeping to allow calling get
>>> q.get(); print("Get returned!")
T2 awoke, putting
'Hello world!'
Get returned!
>>> 1491387024.89 T2 running
qsize 0
1491387025.89 T2 running
qsize 0
1491387026.89 T2 running
qsize 0
1491387027.89 T2 running
qsize 0
1491387028.9 T2 running
...