파이썬에서 병렬 I/O를 실행하고 싶을때, 자연스럽게 스레드 사용을 고려하지만 팬아웃을 수행하고자 할 때 스레드를 사용할 경우 큰 단점을 마주하게된다.
Thread 인스턴스를 서로 안전하게 조율하려면 특별한 도구가 필요하다
스레드는 메모리를 많이 사용하며, 스레드 하나당 약 8MB가 더 필요하다.
스레드를 시작하는 비용이 비싸고, 컨텍스트 전환에 비용이 들기 때문에 스레드는 성능에 부정적인 영향을 미친다.
코드가 문제가 생길 때 디버깅을 하기가 매우 어렵다
#예시
"""
이 함수를 가리키는 Thread 인스턴스를 실행하고, 프로그램의 sys.stderr출력을
메모리상의 StringIO 버퍼로 전달하여 무슨 일이 생기는지 볼 수 있다.
"""
import contextlib
import io
fake_stderr = io.StringIO()
with contextlib.redirect_stderr(fake_stderr):
thread = Thread(target=game_logic, args=(ALIVE,3))
thread.start()
thread.join()
print(fake_stderr.getvalue())
#결과
"""
Exception in thread Thread-226:
Traceback (most recent call last):
File "threading.py", line 917, in_bootstrap_inner
self.run()
File "threading.py" line 865, in run
self._target(*self._args, **self._kwargs)
File "example.py", line 193, in game_logic
raise OSError('I/O 문제 발생')
OSError: I/O 문제 발생
"""
스레드에는 많은 단점이 있으므로 스레드를 시작하고 실행하는데 비용이 들기 때문에 스레드가 많이 필요하면 상당한 메모리를 사용한다.
스레드 사이를 조율하기 위해서 Lock과 같은 특별한 도구를 사용한다.
스레드를 시작하거나 스레드가 종료하기를 기다리는 코드에게 스레드 실행 중에 발생한 예외를 돌려주는 파이썬 내장 기능이 없으므로 스레드 디버깅이 더 어려워진다.