[threading] ipynb에서 daemon thread 가 적용되지 않는 것에 대해서

2024. 3. 5. 23:08학습/python

ipynb 에서 실행이 daemon = True 가 잘적용되는것 처럼 보이다가 그대로 thread가 진행되는 모습을 보여준다.

 

ipynb에서 daemon thread 가 적용되지 않는 것에 대해서

 

선요약

 

원인 : 단일 셀의 실행이 끝났다고 해서 Python 인터프리터가 종료되는 것은 아니므로 백그라운드 스레드가 계속 실행됩니다.

ipynb 말고 py 에서 실행하면 문제 없이 데몬스레드가 종료됨.

 

 

Treading 모듈
import threading
import time

def first():
    print(11)
    time.sleep(0.1)
    print(22)
    time.sleep(0.1)
    print(33)
    time.sleep(0.1)
    
def second():
    print(1111)
    time.sleep(0.1)
    print(2222)
    time.sleep(0.1)
    print(3333)
    time.sleep(0.1)
    
def loop():
    for i in range(1,15):
        print(f"반복문:{i}")
        time.sleep(0.1)

 

위의 함수를 순서대로 실행시킨다면 first()를 완료하고 second(), 그다음 loop를 차례대로 실행할 것입니다.

 

간단한 계산같은경우 아주 빠르게 처리하겠지만, 예를 들어time.sleep() 같이 물리적으로 시간을 정해놓은 작업같은 경우 동시에 여러개를 돌리면 안되나? 라는 생각을 할 것입니다. 그것을 해결하기 위한 것이 Threading, 파이썬에서 다중 스레딩을 사용하게 해주는 모듈입니다. 

 

Threading을 사용하면 어떻게 결과가 나올까요?

동시에 실행됩니다.

 

 

Daemon Thread?

 

다중 스레딩을 통해 여러개의 스레드를 동시해 실행하였습니다. 하지만 도중에 우선순위나 종속성, 지원에 의해서 특정 스레드가 실행을 완료한다면, 관련된 모든 스레드가 종료시키고 싶다면 어떻게 할까요?

 

예를 들어 A app을 실행한다면 그것을 지원하기위한 로그 기록 B, 상태 모니터링 C, 백그라운드 처리 D 등이 있습니다. 이는 주 프로그램의 작업 완료와는 별개로 진행되며, 주 프로그램이 종료되면 더 이상 필요하지 않은 작업 등입니다.

 

따라서 데몬 스레드는 주 프로그램이 종료될 때 자동으로 종료되는 특징을 가지고 있습니다.

 

이를 python 에서는 thread의 daemon 속성으로 지정할 수 있습니다. (defautl 값은 False로 되어 있습니다.)

 

어라? 왜 종료가 안되고 모두 실행 시켜 버리는 것일까요?

 

이 글의 가장 위의 움짤처럼 

import threading
import time

def daemon_thread():
    print("데몬 스레드 시작")
    time.sleep(2)
    print("데몬 스레드 종료")  # 메인 스레드가 먼저 종료되면 이 메시지는 출력되지 않습니다.

def non_daemon_thread():
    print("일반 스레드 시작")
    print("일반 스레드 종료")

daemon = threading.Thread(name='daemon_thread', target=daemon_thread)
daemon.setDaemon(True)  # 데몬 스레드로 설정

non_daemon = threading.Thread(name='non_daemon_thread', target=non_daemon_thread)

daemon.start()
non_daemon.start()

이 함수를 실행해도 똑같이 

 

데몬 스레드? 알빠임? 하고 끝까지 실행해 버립니다.

 

 

ipynb (주피터 노트북) 의 특징

 

주피터 노트북에서 각 셀은 독립된 실행 단위입니다. 즉, 각 셀은 별도로 실행될 수 있으며, 실행 순서는 사용자에게 달려 있습니다. 그러나 환경이나 컨텍스트는 독립적이지 않습니다.

주피터 노트북의 모든 셀은 동일한 커널을 공유합니다. 즉, 한 셀에서 정의한 변수나 함수는 다른 셀에서도 사용할 수 있습니다. 예를 들어, 한 셀에서 x = 10이라고 선언하면, 이후에 실행되는 모든 셀에서 x의 값이 10임을 알 수 있습니다.

 

이 글에서 가장 중요한 것은
ipynb에서는 단일 셀의 실행이 끝났다고 해서 Python 인터프리터가 종료되는 것은 아니므로 백그라운드 스레드가 계속 실행됩니다.

 

py 로 실행하면 잘 나옵니다.

 

 

 

 

 

참고링크 

https://discuss.python.org/t/daemon-parameter-in-threading-thread-function-isnt-working-while-code-is-executing-in-a-ipynb-file/42977/8

 

Daemon parameter in threading.Thread() function isn't working while code is executing in a .ipynb file

I think the output should be 08:31:35: Main : before creating thread 08:31:35: Main : before running thread 08:31:35: Thread 1: starting 08:31:35: Main : wait for the thread to finish 08:31:35: Main : all done But actually the output is 08:31:35: Main : be

discuss.python.org

 

728x90