아니요, 스레드 안전은 잠금 장치를 통해서만 보장 될 수 있습니다.
self.cnt += 1
은 멀티 스레딩 할 때 두 번 실행될 수 있습니까?
두 개의 스레드가 실행 중이면 두 번 실행됩니다. 세 스레드, 세 번, 등등. 나는 당신이 당신이 정말로 당신이 콘텍스트 관리자와 관련하여 이러한 스레드를 만들고 실행하는 방법을 보여줄지 모르겠다.
은 같은 맥락 관리자 예를 들어, 멀티 스레딩에, 어떻게 든
__enter__
두 번 호출하고
__exit__
한 번만 호출 할 수 있기 때문에 self.cnt 최종 결과가 1이라고 할 수 있습니까?
예, 최종 결과는 0이 아니지만 입력 및 종료의 비대칭 호출로 가정하는 메커니즘을 통한 것은 아닙니다. 심지어 최종 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)
당신은 불가피하게 발견 할 것이다 : 여러 스레드에서 동일한 컨텍스트 관리 프로그램 인스턴스를 사용하는 경우, 당신은 너무 같은 오류를 재현 할 수있는 간단한 예를 구성 할 수 있습니다 네 옵 코드로 해석되는이 대부분 +=
운영자에 의해 발생
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
: 모든 스레드가 시작 시작 및 종료 관련 모든 더 많거나 적은 쌍으로 호출 된 경우에도, 동일한 코드로 끝나면하지만 개별 opcode만이 보장됩니다. GIL에 의해서만 안전하다. 자세한 내용은이 질문에서 찾을 수 있습니다 : Is the += operator thread-safe in Python?
멀티 스레딩에서 같은 인스턴스가 무슨 뜻입니까? 관계없이 각각의 스레드에게 당신이 사용하고있는 컨텍스트 관리자의 인스턴스를 제공한다면 관련성이 없습니다. 액세스 된 데이터가 스레드간에 공유되는 경우, 액세스는 mutex/lock을 사용하여 관리해야합니다. – metatoaster
@metatoaster 각 스레드마다 고유 한 컨텍스트 관리자가 있지만 동의합니다. 동료는 __enter__이 인스턴스 메소드 일 뿐이며 두 번 호출 될 수 있으므로 스레드 안전하지 않으므로 동일한 contextmanager 인스턴스의 __enter__은 스레드가 아닙니다. 안전한. 나는 잃어버린 느낌을 느낀다 – est
각 스레드가 자신의 인스턴스를 가지고 있다면 공유 된 데이터가 없다. – martineau