Python을 잘 사용하진 않지만 궁금해서 찾아보다 알게 된 내용을 정리하기로 하였다.
hanging-threads이라는 모듈을 사용하면 지정된 시간마다 스택을 덤프 하고 비교하여 변화가 없으면 교착 상태라고 판단한 다음 해당 스레드의 로그를 띄워주게 된다.
pip을 이용하여 우선 hanging-threads를 받아주어야 한다.
리눅스에서는 다음의 명령어로
pip install hanging-threads
윈도우에서는 다음의 명령어로 설치하면 된다.
py -m pip install hanging_threads
그다음은 교착 상태를 감지하고 싶은 소스에서
from hanging_threads import start_monitoring
monitoring_thread = start_monitoring(seconds_frozen=10, test_interval=100)
위의 코드를 작성하면 자동으로 감지가 된다.
seconds_frozen은 몇 초 동안 스택 덤프에 변화가 없으면 교착 상태로 판단하는지 지정하는 파라미터고,
test_interval은 스택 덤프를 작성하는 주기인 것 같다. (제대로 본 것이 아니라 맞는지 모르겠다.)
seconds_frozen은 초 단위이고, test_interval은 ms 단위이다.
테스트를 하기 위해 hang을 발생시키는 코드에 사용해 보았다.
from hanging_threads import start_monitoring
from urllib.request import urlopen
start_monitoring(seconds_frozen=10, test_interval=100)
url = 'http://localhost:5555'
response = urlopen(url)
print(response.read())
nc -l 5555
nc(netcat) 명령어로 5555 포트를 열어주고 위의 코드를 실행시키면 아무것도 읽히지 않기 때문에 hang이 발생하게 된다.
위 코드의 실행 결과는
위와 같이 나온다.
MainThread에서 hang이 발생했다는 알림을 띄어주고 해당 로그을 보여준다.
다음은 deadlock을 발생시키는 코드에 사용해 보았다.
from hanging_threads import start_monitoring
import threading
import time
start_monitoring(seconds_frozen=10, test_interval=100)
l1 = threading.Lock()
l2 = threading.Lock()
def f1(name):
print('thread', name, 'about to lock l1')
with l1:
print('thread', name, 'has lock l1')
time.sleep(0.3)
print('thread', name, 'about to lock l2')
with l2:
print('thread', name, 'run into deadLock,\nthis line will never run')
def f2(name):
print('thread', name, 'about to lock l2')
with l2:
print('thread', name, 'has lock l2')
time.sleep(0.3)
print('thread', name, 'about to lock l1')
with l1:
print('thread', name, 'run into deadlock,\nthis line will never run')
if __name__ == '__main__':
t1 = threading.Thread(target=f1, args=['t1'])
t2 = threading.Thread(target=f2, args=['t2'])
t1.start()
t2.start()
위 코드의 실행 결과는
위와 같이 나온다.
MainThread 말고 교착 상태가 발생한 두 스레드의 로그까지 출력한다.
찾고 나서 테스트해보니까 디버그 용도로 사용하기 좋을 것 같은데 그럴 거면 gdb를 사용하는 거랑 뭐가 다른지 모르겠다.
교착 상태가 발생했을 때 콜백 함수로 어떠한 조치를 취할 수 있도록 하는 기능이 있었으면 좋았을 것 같다.
Python 3.3부터 faulthandler를 사용하면 된다는 내용이 git에 적혀 있는데 다음에 시간이 생기면 이건 어떻게 사용하는 건지 알아봐야겠다. (근데 난 파이썬을 안 쓴다.)
'Etc > 2021' 카테고리의 다른 글
[Eclipse] JavaScript semi-colon expected 에러 "진짜" 해결하기 (2) | 2021.07.13 |
---|---|
[Git] .gitignore 파일 쉽게 생성하기 (0) | 2021.07.08 |
[GCP] GCP(Google Cloud Platform)에서 AOSP Cuttlefish를 이용한 안드로이드 웹 에뮬레이터 사용하기 (feat. 오징어 발사) (0) | 2021.06.04 |
[GCP] GCP(Google Cloud Platform) 중첩 가상화 환경 구성하기 (0) | 2021.06.04 |
[Chrome 확장] Udemy(유데미) 한글 자막으로 보는 법 (feat. 크롬 확장) (17) | 2021.05.21 |