2012-07-21 11 views
7

qsize()のdocには次のように書かれています。キューのおおよそのサイズを返します。なぜPythonのキューはqsize()におおよそのサイズを返しますか?

なぜこのキューの正確なサイズを返すことができないのですか?私はキューが複数のスレッドによってアクセスされる可能性があると理解していますが、現時点では関数を呼び出すと、その時点の正確なサイズを返すことは可能です。

+1

は何瞬間?メソッドのリターン中にキューのサイズが変更された可能性があります。 –

答えて

24

他のスレッドがアクセスしているからです。 qsize()から返されたサイズを使用しようとするときに、キューが変更されている可能性があります。ドキュメントが次のようなものを読んでいると良いでしょう。

キューのサイズを返します。マルチスレッド環境では、サイズはいつでも変更できるため、これは実際のサイズの近似値に過ぎません。私は「おおよその言葉の明確な選択ではありませんが、ネッドは言及して、彼らは単に時間t1のキューのサイズが7だったのですることはするという意味ではありませんことを指摘しようとしていることに同意し

5

後で値をプッシュまたはポップすると、サイズは7になります。

問題は、プッシュ/ポップするときにqsizeから戻ってくるサイズが正しいと仮定すると、そのキューの値がマルチスレッド環境で予期しない動作をする可能性があります。例えば

q = Queue() 
if q.qsize > 0: # size is 1 here 
    # another thread runs here and gets an item from your queue 
    # this get fails and throws an exception in your thread: 
    item = q.get(False) 
    # do whatever processing with item you need to do 

「あなたが跳躍する前に見て、」これはLBYLの一例であり、複数のスレッドがキューにアクセスしているときには、こちらの潜在的な競合状態の危険です。あなたがEAFPを好むか、「許可よりも許しを求めるが容易」と次のことを行う必要があります。この場合

from Queue import Queue, Empty 
import time 
q = Queue() 
try: 
    item = q.get(False) 
    # do whatever processing with item you need to do 
except Empty: 
    time.sleep(1) 
+0

..またはセマフォを使用して、キューにエントリがあることを保証してください。 –

+6

キューはすでに同期されています。上に追加しないでください。例外と共に 'q.get'を使うことは、スレッドセーフな方法で項目を取得するのに最適です。 –

関連する問題