3

Python のスレッドセーフQueueオブジェクトにはQueue.full()、次のドキュメントで名前が付けられた便利な関数があります。

キューがいっぱいの場合は True を返し、それ以外の場合は False を返します。full() が True を返す場合、その後の get() の呼び出しがブロックされないという保証はありません。同様に、full() が False を返す場合、その後の put() の呼び出しがブロックされないという保証はありません。

put()キュー内の複数のスレッド項目と複数のスレッド項目があるマルチスレッド シナリオでget()は、競合状態が発生することは明らかです。しかし、1 つのスレッドだけが を使用しput()、1 つの異なるスレッドが を使用しget()ている場合、 の値はfull()信頼できませんか?
これは Python 実装固有の質問ですか? もしそうなら、CPythonの答えは何ですか?

4

2 に答える 2

4

すべてを実行するために 1 つのスレッドのみを使用しているという意味であれば、そうです。他に何もアクセスしていない場合、それを変更する方法はありません。

全体で 2 つのスレッドを意味する場合、いいえ、競合状態の可能性はまだあります。

いずれにせよ、本当の問題は、なぜこのようにしたいのかということです。試してみて、失敗した場合は例外をキャッチしてください。これが Python のやり方です。

try:
    some_queue.get_nowait()
except queue.Empty:
    do_something_else()

これには、将来スレッドセーフであるという利点があり、どのような状況でも競合状態を回避できます (競合状態を引き起こすのにスレッドは必要ありません。チェックと取得の間に誤ってコードを変更する呼び出しを行うことができます)。 .

編集: larsmansが以下のコメントで指摘したように、競合状態に関する他の問題の中でも、CPython はある時点で削除される可能性が高いとQueue.full()マークしているため、それを避ける別の理由があります。

于 2012-05-29T14:25:39.023 に答える
0

Queue()のisfull-informationの更新が遅れているのを私はかつて観察しました。これは、それ自体がputやgetなどを行うために特別なスレッド(!)を使用していたためです。したがって、I(!)が1つのスレッドだけを使用している場合でも、これに依存することはありません。多分キューはそうではありません。

于 2012-05-29T15:06:05.057 に答える