4


1

Pythonグローバル変数はスレッドセーフですか?

編集:トルネードのようなシングルスレッドのWebフレームワークでグローバル変数が安全かどうかを尋ねるイム

グローバル変数からデータベース接続を取得するmongoengine ormを使用しているim:

_get_db() # gets the db connection

また、シングルスレッドのPython Webフレームワークであるトルネードを使用しています。 特定のビューでは、データベース接続を取得し、 `DBRef`オブジェクトを参照解除する必要があります[外部キーと同様]:

# dereference a DBRef
_get_db().dereference(some_db_ref)

`_get_db`によって返される接続はグローバル変数なので、衝突の可能性があり、間違った値が間違ったスレッドに返されますか?

4 Answer


3


Pythonオブジェクトと対話する場合、GILを保持するには常にスレッドが必要です。 変数を保持する名前空間は、Pythonオブジェクト(変数の種類に応じて、frameobjectまたはdictのいずれかです)。複数のスレッドで変数を取得または設定することは常に安全です。 ごみデータを取得することはありません。

ただし、どのオブジェクトを取得するか、割り当てるときにどのオブジェクトを置き換えるかについては、通常の競合条件が適用されます。 x + = 1`のようなステートメントは、スレッドセーフではありません。getとストアの間で異なるスレッドが実行され、 x`の値が変更されて上書きされる可能性があるためです。


2


MongoEngineがPyMongoをラップしていると仮定すると(そして、そうだと思います)、大丈夫です。 PyMongoは完全にスレッドセーフです。


1


いいえ、ロックはPythonで使用するのは非常に簡単です。 try:finally:パターンを使用して、グローバル変数を変更した後にロックが解除されるようにします。


0


他の変数よりも多かれ少なかれスレッドセーフにするグローバルについては何もありません。 異なるスレッドで実行した場合、操作が失敗したり、誤った結果を返す可能性があるかどうかにかかわらず、ベストプラクティスは、スレッド間で共有されるデータを保護することです。

私があなたを正しく読んでいるなら、あなたは変数がシングルスレッド環境で安全かどうか尋ねています。 この場合、並行プロセス間でデータが共有されない場合、変数は安全です(結局、それを中断する可能性のあるものは他に実行されていません)。