파이썬 쓰레드(thread)를 중간에 중단(kill, terminate)시키는법

일단 파이썬 쓰레드가 돌아가고 있는데 강제로 terminate 가는 것을 별로 좋지 않다고 한다. 이유는 닫아져야할 중요한 리소스가 그대로 남아있을 수 있어서 그렇다고… 그런데 별로 좋지 않다고 해도 그냥 쓰면 쓰는거지하고 쓰는 사람도 있고. 쫄아서 안쓰는 사람도 있는데….

어쨌든 아무튼 특정 시간이 지나서 스레드를 멈추어야할 필요가 있거나, 언제든 내 맘대로 스레드를 중단하고 싶을 때 raise Exception 을 해서 스레드를 멈출 수 있다.

# Python program raising 
# exceptions in a python 
# thread 
  
import threading 
import ctypes 
import time 
   
class thread_with_exception(threading.Thread): 
    def __init__(self, name): 
        threading.Thread.__init__(self) 
        self.name = name 
              
    def run(self): 
  
        # target function of the thread class 
        try: 
            while True: 
                print('running ' + self.name) 
        finally: 
            print('ended') 
           
    def get_id(self): 
  
        # returns id of the respective thread 
        if hasattr(self, '_thread_id'): 
            return self._thread_id 
        for id, thread in threading._active.items(): 
            if thread is self: 
                return id
   
    def raise_exception(self): 
        thread_id = self.get_id() 
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 
              ctypes.py_object(SystemExit)) 
        if res > 1: 
            ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0) 
            print('Exception raise failure') 
       
t1 = thread_with_exception('Thread 1') 
t1.start() 
time.sleep(2) 
t1.raise_exception() 
t1.join() 

참고로 라이즈 익셉션을 호출하면 ‘그’ 스레드 진행은 멈추지만 메인스레드는 멈추지 않는다. 또한 ‘그’ 스레드에서 sys.exit(0) 로 스레드를 정상종료해도 ‘그’ 스레드만 종료되지 메인스레드는 그대로 살아있다. 그럼 메인스레드를 어떻게 종료하냐? 간단하다. 그냥 평소 하듯이 메인스레드에서 sys.exit() 를 쓰면 된다. 메인스레드를 종료하면 다른 스레드는 함께 죽는다. 그러나 메인스레드가 아닌 스레드들은 종료해도 지들만 죽지 메인스레드가 함께 죽는것은 아니다.

그럼 ‘그’ 스레드에서 프로세스를 종료하려면 어떻게 해야하나? 그냥 간단하게 아래처럼 ㅋ

pid = os.getpid()
os.kill(pid, 2)

자식스레드란 말이 개인적으로 어째 어감이 불편해서 ‘그’스레드라는 말을 써봤다.

참조페이지 : https://www.geeksforgeeks.org/python-different-ways-to-kill-a-thread/

Leave a Comment