6

現在キューに入っているすべてのアイテムを取りたいと思っています。他のスレッドは常に相手側にアイテムを置いており、現在キュー内のすべてのアイテムを取得したいと思う毎週です。Pythonのマルチプロセッシングキュー(-1)を空にする好きな方法

好むそこにいくつかの理由です:今、ドキュメントは、具体的QSIZE()> 0は、getでブロックからキューを防ぐことはできませんと言う

res = [] 
while q.qsize > 0 : 
    res.append(q.get()) 

または

res = [] 
while True : 
    try : 
     res.append(q.get(block=False)) 
    except Queue.Empty : 
     break 

が、これは、複数のスレッドが出力から取り出すことができる場合にのみ本当ですか?

キュー。 qsize()キューのおおよそのサイズを返します。 qsize()> 0は、後続のget()がブロックされないことを保証しません。また、qsize()< maxsizeはput()がブロックしないことを保証しません。

これは、2番目のフォームが常に優先されるべきであることを意味しますか? EAFPとそのすべて?また、q.qsize()を呼び出すためのコストはありますか?カウントするためにキューのもう一方の端をブロックしていますか?

私は自分自身に2番目のフォームを使用するように話したことがありますが、それは私にとってははるかにクリーンではないようです。

答えて

5

はい、常に第2の変種を使用してください。APIのドキュメントは、文書化されていない実装よりも一般的に信頼性が高く(必要があります)現在のmultiprocessingの実装では、特殊なケースでは、qsize() > 0の場合はブロックされませんが、将来のバージョンのPythonではこのようになることは保証されていません。

現在のバージョンのPythonでは、消費するプロセスが1つだけであれば、最初のバージョンも信頼性が高くなります。呼び出すqsizeintenally invokes sem_getvalue on Linux and WaitForSingleObjectEx on Windows;どちらも何もロックしていません。 (Linux呼び出しの場合はWindowsの呼び出しのため、これはマンページで説明されていますが、それは強い推測です)。

複数のコンシューマを持ち、そのうちの1つがキュー全体を確実に読み取るようにするには、あなたのループを囲む追加のロックを使用する!

関連する問題