Python:为什么Queue.queue的一些方法“不可靠”?

12
Queue模块的queue类中,有几个方法,分别是qsizeemptyfull,其文档声称它们“不可靠”。
它们的不可靠性体现在哪里?
我注意到在Python文档网站上,关于qsize的说明如下:

请注意,qsize() > 0不能保证随后的get()不会阻塞,qsize() < maxsize也不能保证put()不会阻塞。

我个人不认为这种行为是“不可靠”的。但是,“不可靠”是否指的是这个,还是这些方法中存在更加严重的缺陷?

5
文档毫无用处。在文档中仅仅说“这个函数不可靠”是不够的,需要详细说明其不可靠的具体原因。 - Glenn Maynard
2
@Glenn,请查看http://docs.python.org/library/queue.html:其中并没有出现“reliable”和“unreliable”这些词。代码中简洁的一行文档字符串使用“not reliable”作为有用的速记,当然你可以去手册查看完整细节:在代码本身中拥有短总结,除了手册中的完整描述之外,远非无用。 - Alex Martelli
2
事实上,当前的文档(谷歌链接我到旧文档)已经取代了2.5文档,而后者明确表示“不可靠”(http://www.python.org/doc/2.5.2/lib/QueueObjects.html)。显然,Python开发人员同意我的看法,因为他们用真正的描述替换了无用的2.5文本。请不要有态度,也不要对我进行讲课。 - Glenn Maynard
当前文档:http://www.python.org/doc/current/library/queue.html#queue-objects。 - Glenn Maynard
@Glenn,cool-RR:关于_Queue.qsize(),empty(),full()_的当前文档肯定可以改进,以说明多线程行为的常规注意事项,并链接到适当的部分。这里是如何提交文档错误。我认为值得提交。 - smci
显示剩余2条评论
3个回答

13

是的,文档在此处使用“不可靠”来精确传达这个意思:例如,在某种意义上, qsize 不告诉你现在有多少条目,这个概念在多线程世界中并不一定非常有意义(除非在采取同步预防措施的特定点)-- 它告诉你它之前有多少条目......当你根据该信息采取行动时,即使在下一次操作码中,队列可能会有更多的条目、更少的条目或者根本没有条目,这取决于其他线程在此期间所做的事情(如果有的话;-)。


3
“Unreliable”这个词意味着可能存在各种问题。对于某些使用情况(例如,从只有一个生产者线程的队列中检测插入是否会阻塞),这些函数应该是完全可靠的。“Unreliable”的含义是没有意义的。 - Glenn Maynard
3
@Alex Martelli: qsize报告的队列大小为什么不是实时的?毕竟,调用qsize的线程持有互斥锁,这意味着它是在此时间点上访问队列的唯一线程。或者您使用"现在"这个术语是指"在您完成调用qsize之后的那一刻"? - Ram Rachum
5
这里的尺寸是指在调用线程持有互斥锁时的尺寸,该锁会在finally语句块中释放,作为return的一部分;这个时间点早于调用线程中的代码接收结果的时间点。而"现在"指的是将结果绑定到变量或以任何其他方式使用结果的时间:到那时,被绑定或以其他方式使用的结果可能已经过时。 - Alex Martelli
@Glenn,请看我在问题的回复评论中对您的评论的回复:远非毫无意义或无用,问题中极为简洁的摘要有效地和有意义地提醒读者手册中更详细解释。例如,即使full为true,这也并不意味着在单个生产者场景中你将会被阻塞...在这种极端专业化的情况下,你知道没有其他线程会导致false->true的转换,但您不知道在这种人工情况下true->false的转换!-)。 - Alex Martelli

2

我不知道你指的是哪个队列模块,请提供链接。

一个可能导致不可靠的来源是:通常情况下,一个队列由一个线程读取和另一个线程写入。如果只有一个线程访问队列,则可以实现可靠的qsize()、empty()和full()方法。但一旦其他线程介入,这些方法的返回值在你测试时可能已经过时了。


Queue.py,标准库的一部分。 - Ram Rachum
Python标准库中有一个Queue.py模块,我在问题中加了注释以指向它的文档。源代码位于http://svn.python.org/view/python/trunk/Lib/Queue.py?view=markup。 - Alex Martelli
啊,好的,我傻乎乎地以为队列不能在stdlib中,因为它不符合PEP8的命名规范。我想这是个例外。谢谢你提供的链接! - user9876

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接