いいえ、スレッドの安全性はロックによってのみ保証されます。
マルチスレッド時にself.cnt += 1
が2回実行される可能性はありますか?
2つのスレッドが実行されている場合は、2回実行されます。 3つのスレッド、3回など。あなたが本当にこれによって何を意味しているのかわからない、おそらくあなたのコンテキストマネージャーとの関連でこれらのスレッドを構築/実行する方法を私たちに教えてください。
それは同じコンテキストマネージャのインスタンスのために、マルチスレッドで、何とか
__enter__
が二回呼ばれることと
__exit__
は一度だけ呼び出され、そうself.cnt最終結果が1であることは可能ですか?
はい、最終的な結果はゼロではありませんが、入力と終了の非対称な呼び出しを想定しているメカニズムではできません。あなたは必然的に最終shared_context.cnt
は、多くの場合でも、0
でバックアップ終了しないことがわかります
from threading import Thread
class Context(object):
def __init__(self):
self.cnt = 0
def __enter__(self):
self.cnt += 1
def __exit__(self, exc_type, exc_value, traceback):
self.cnt -= 1
shared_context = Context()
def run(thread_id):
with shared_context:
print('enter: shared_context.cnt = %d, thread_id = %d' % (
shared_context.cnt, thread_id))
print('exit: shared_context.cnt = %d, thread_id = %d' % (
shared_context.cnt, thread_id))
threads = [Thread(target=run, args=(i,)) for i in range(1000)]
# Start all threads
for t in threads:
t.start()
# Wait for all threads to finish before printing the final cnt
for t in threads:
t.join()
print(shared_context.cnt)
:あなたが複数のスレッドで同じコンテキストマネージャのインスタンスを使用する場合は、そのようなエラーを再現することができ、簡単な例を構築することができます4つのオペコードに解決されている。これは主に+=
オペレータによって引き起こされる
enter: shared_context.cnt = 3, thread_id = 998
exit: shared_context.cnt = 3, thread_id = 998
enter: shared_context.cnt = 3, thread_id = 999
exit: shared_context.cnt = 3, thread_id = 999
2
...
enter: shared_context.cnt = 0, thread_id = 998
exit: shared_context.cnt = 0, thread_id = 998
enter: shared_context.cnt = 1, thread_id = 999
exit: shared_context.cnt = 0, thread_id = 999
-1
:すべてのスレッドが開始され、出入りがすべて多かれ少なかれペアで呼ばれていても、まったく同じコードで終了したときけれども個々のオペコードのみが保証されますGILだけであれば安全です。詳細は次の質問にあります:Is the += operator thread-safe in Python?
マルチスレッドではどういう意味ですか?どちらのコンテキストマネージャを使用していても、それぞれのスレッドに独自のインスタンスを与えても、関係はありません。アクセスされるデータがスレッド間で共有されている場合、それらへのアクセスはmutexes/lockを使用して管理する必要があります。 – metatoaster
@metatoaster各スレッドには独自のコンテキストマネージャがありますが、私の同僚は '__enter__'は単なるインスタンスメソッドであると言います.2回呼び出される可能性があるのでスレッドセーフではないため、同じcontextmanagerインスタンスの' __enter__'はスレッド安全。私は失われて感じる – est
各スレッドが独自のインスタンスを持っている場合、共有データはありません。 – martineau