Python队列块超时不会超时 - 任何想法为什么?

tk.*_*lee 2 python queue multithreading

我希望以下python代码将在控制台输出中打印"Timeout:".

它有一个生成对象的线程.消费者线程将获取排队的对象并将其打印出来.

没有发生预期的Queue Get()超时.有什么想法吗?

输出为:(没有预期的"超时:"打印输出.)

1390521788.42  Outputting: o={'test': 2, 'sName': 't1'} 
1390521791.42  Outputting: o={'test': 3, 'sName': 't1'}
1390521794.42  Outputting: o={'test': 4, 'sName': 't1'}
1390521797.42  Outputting: o={'test': 5, 'sName': 't1'}
end while sName=t1 
Run Code Online (Sandbox Code Playgroud)

这是在Linux中使用Python 2.7进行测试的.

import threading, Queue, time

class ProduceThread(threading.Thread):
    def __init__ (self, start_num, end, q, sName, nSleep=1):
        self.num = start_num
        self.q = q
        threading.Thread.__init__ (self)
        self.m_end = end;
        self.m_sName = sName;
        self.m_nSleep = nSleep;

    def run(self):
        o = {};
        o['sName'] = self.m_sName;
        while True:
            if self.num != self.m_end:
                self.num += 1
                o['test'] = self.num;
                # self.q.put(self.num)
                self.q.put(o)
                time.sleep(self.m_nSleep)
            else:
                break
        print "end while sName=%s" % (self.m_sName);

myQueue = Queue.Queue()
myThread = ProduceThread(1, 5, myQueue, 't1', 3); myThread.start()
# myThread2 = ProduceThread(1, 5, myQueue, 't2', 3); myThread2.start()
# myThread3 = ProduceThread(1, 5, myQueue, 't3', 3); myThread3.start()

def Log(s):
    t = time.time();
    print "%s  %s" %(t, s)

################################################################
#  Consumer Loop
while True:
    if not myQueue.empty():
        try:
            o = myQueue.get(block=True, timeout=1)
            Log( "Outputting: o=%s" % (o));
        except:
            ###### I expect the Timeout to happen here. But it is not.
            Log( "Timeout: " );
            pass;
    # time.sleep(1)
Run Code Online (Sandbox Code Playgroud)

Tim*_*ers 6

好吧,想一想:

if not myQueue.empty():
    try:
        o = myQueue.get(block=True, timeout=2)
        Log( "Outputting: o=%s" % (o));
Run Code Online (Sandbox Code Playgroud)

抛开你不应该依赖Queue.empty()方法.查看文档:

如果empty()返回True,则不保证对put()的后续调用不会阻塞.类似地,如果empty()返回False,则不保证对get()的后续调用不会阻塞.

但是,在这种简单的上下文中,它"非常可靠";-)现在你的超时怎么可能发生?当且仅.get()当您的队列为时才进行尝试.但是,.get()当你的队列为空时,你永远不会执行你的,因为你的:

if not myQueue.empty():
Run Code Online (Sandbox Code Playgroud)

测试!实际上,你问这个:

当我确定某些东西在队列中时,我只尝试做.get().所以我确定.get()会立即成功.那么为什么它不会超时?

除掉

if not myQueue.empty():
Run Code Online (Sandbox Code Playgroud)

声明完全然后它最终会超时.

  • 很聪明; 除了有非常罕见的竞争条件之外,他编写的代码是_fails_,除非有非常罕见的竞争条件,而且更容易调试.:) (3认同)