Python 队列 block 超时不会超时 - 知道为什么吗?

标签 python multithreading queue

我预计以下 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 

这是在 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)

最佳答案

好吧,想想这个:

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

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

If empty() returns True it doesn’t guarantee that a subsequent call to put() will not block. Similarly, if empty() returns False it doesn’t guarantee that a subsequent call to get() will not block.

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

if not myQueue.empty():

测试!实际上,您是在问这个:

I only try to do .get() when I'm sure something is on the queue. So I'm sure .get() will succeed immediatey. So why doesn't it ever time out?

删除

if not myQueue.empty():

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

关于Python 队列 block 超时不会超时 - 知道为什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21320621/

相关文章:

multithreading - Thread.Sleep() 除了模拟持久任务之外还有其他用途吗?

python - 为什么 python 框架安装指南会建议对某些必需的包使用 easy_install 而对其他包使用 pip?

Python - 正确杀死/退出 future 线程?

.net - VolatileWrite bool 值

c++ - 如何一直运行固定数量的线程

c++是否有默认数据类以合理的速度进行基于排序索引的访问?

java - Queue的并发版本需要异常

python - 功能变化不大。面具。 Python

python - AWS EMR 在集群中所有已经运行的机器上执行 "bootstrap"脚本

javascript - jQuery 中的非嵌套动画序列?