티스토리 뷰

Python

쓰레딩(Threading

˙ᵕ˙ 2020. 8. 29. 01:13

파이썬의 스레딩(Threading)

Single Thread와 Multi Thread

  • 프로세스 : 완전히 구별되는 별개의 프로그램이 수행되는 과정

  • 스레드 : 단일 프로세스 내에서 병행적으로 운영되는 함수 크기의 실행단위

  • Single Thread : 프로그램의 흐름이 단일로 이루어지는 프로그램

  • Multi Thread : 운영체제에서 실행중인 하나의 프로그램인 프로세스 내에서 실행되는 세부 작업단위를 말하며 하나의 프로세스에서 여러 개의 스레드가 병행적을 처리되는 것

스레드 생성

메소드 설명
active_count() 실행 중인 Thread 객체의 수를 리턴하며 enumerate()의 목록 리턴 길이와 동일하다.
current_thread() 현재 실행 중인 프로세스의 스레드를 지원하는 Thread 오브젝트를 리턴한다.
get_ident() 현재 스레드의 '스레드 ID'를 리턴한다.
enumerate() 현재 실행 중인 Thread 객체 모든 목록을 리턴하며 목록에는 데몬 스레드(daemon thread) current_thread() 의 생성 더미 스레드 객체, 그리고 메인 스레드를 가진다.
main_thread() main thread 오브젝트를 리턴하며 메인 스레드는 python 인터프리터가 시작된 스레드를 말한다.
settrace( func ) threading 모듈을 사용하여 시작한 모든 스레드에 추적 기능을 설정한다.
setprofile( func ) threading 모듈을 사용하여 시작한 모든 스레드 프로파일 기능을 설정한다.
stack_size( [ size ] ) 새 스레드를 만들 때 스레드 스택 크기를 리턴한다. 옵션 size는 0 또는 32,768(32KiB) 이상의 양의 정수이다.
TIMEOUT_MAX 블록함수(Lock.acquire(), RLock.acquire(), Condition.wait() 등)의 timeout 인수에 허용되는 최대값을 리턴
  • 스레드를 생성하는 방법

    • threading.Thread의 생성 자로 호출 할 객체를 전달하는 방법

    • threading.Thread의 서브 클래스를 만들고 run() 메소드를 오버라이드 하는 방법

  •  

    Thread 객체의 생성자

     

class threading.Thread( group = None, target = None, name = None, args = (), kwargs = {}, *, daemon = None)
< 매개인수 목록 >
- gpoup은 None 이어야 하며 미래 ThreadGroup클래스가 구현될 때 확장을 위해 예약 된 인수이다.
- target은 run() 메소드에 의해 시작되는 호출 가능한 객체
- name은 스레드의 이름이며 명시하지 않을 때는 기본적으로 N을 작은 10진수로 "Thread-N"형식의 고유한 이름을 생성
- args는 target을 호출할 때 인수이며 타입은 튜플이다.
- kwargs는 target을 호출할 때 키워드 인수이다.
- daemon은 스레드가 데몬 여부를 명시적으로 설정(None이 아닌경우), None의 경우(디폴트) 데몬 속성은 현재 스레드에서 상속된다.
  • 주요 메소드

메소드 설명
start() 스레드를 시작한다. 객체의 run() 메소드가 단일 처리 스레드 내에서 호출한다.
run() 스레드를 실행할 코드를 작성하며 서브 클래스에서 오버라이드 할 수 있다.
join( timeout = None ) 스레드가 종료 될 때까지 기다리며 timeout 값을 부동 소수점으로 지정할 경우 is_alive()를 호출하여 생존 유무를 확인한다.
getName() 스레드의 이름을 리턴
setName( name ) 스레드의 이름을 지정
ident 스레드 식별자 이며 스레드가 시작되지 않으면 None이다
is_alive() thread가 생존하고 있는지 유무를 True/False로 리턴
daemon 또는 isDaemon() daemon therad 또는 (True) 여부(False)를 나타내bool 값이다. 데몬 스레드를 지정하는 setDaemon()도 있다.
  • 생성자로 객체 전달

import threading

def mythread():
    for i in range(100):
        print(i)

if __name__ == '__main__':
    # mythread를 스레드로 생성
    t = threading.Thread(target=mythread) 
    # 스레드 실행
    t.start()
    for _ in range(50):
        print('Main thread')
  • 메인 스레드와 동시 실행 중이다.

  • Thread를 상속받아 run() 메소드 재정의

import threading

class MyThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):
        for i in range(100):
            print(f'{self.name}: {i}')
    
if __name__ == '__main__':
    t1 = MyThread('야옹이')
    t2 = MyThread('댕댕이')
    t1.start()
    t2.start()

import threading
import time

def mythread(sleep):
    for i in range(10):
        print(f'[{threading.currentThread().getName()}]{i}')
        time.sleep(sleep)

if __name__ == '__main__':
    t1 = threading.Thread(target=mythread, name='야옹이', args=(0.1,))
    t2 = threading.Thread(target=mythread, name='댕댕이', args=(0.2,))
    t3 = threading.Thread(target=mythread, name='꽥꽥이', args=(0.3,))
    t1.start()
    t2.start()
    t3.start()

데몬 스레드

  • 자신의 작업을 실행하는 스레드와는 다르게 다른 스레드로부터 요청을 받아 특정 서비스를 수행하는 작업을 하는 스레드

  • 시스템과 생명주기를 같이 한다.

  • 메인 스레드를 포함해 thread가 데몬스레드만 남았을 때 데몬 스레드는 강제 종료 된다. (setDaemon()을 통해 True/False로 지정가능 - True : 종료)

import threading
import time

def mythread():
    for i in range(10000):
        print(i)

if __name__ == '__main__':
    t = threading.Thread(target=mythread)
    t.setDaemon(True)
    t.start()
  • 스레드가 데몬 스레드 밖에 없으므로 바로 종료

Join ( timeout = None ) 메소드

  • join 메소드는 스레드가 종료 될 때 까지 기다린다.

import threading

def mythread():
    for i in range(100):
        print(i)

if __name__ == '__main__':
    t = threading.Thread(target=mythread)
    t.setDaemon(True)
    t.start()
    t.join()

  • 데몬 생존 유무를 확인하고 지정한 시간동안 join

import threading

def mythread():
    for i in range(10000):
        print(i)

if __name__ == '__main__':
    t = threading.Thread(target=mythread)
    t.setDaemon(True)
    t.start()

    if t.is_alive():
        print('daemon is alive')
        t.join(0.01)

  • 여러개의 스레드를 동시에 실행시켜 모니터링

import threading
import time

def mythread(sleep):
    for i in range(10):
        print(f'[{threading.currentThread().getName()}]{i}')
        time.sleep(sleep)

if __name__ == '__main__':
    t1 = threading.Thread(target=mythread, name='야옹이', args=(0.1,))
    t2 = threading.Thread(target=mythread, name='댕댕이', args=(0.2,))
    t3 = threading.Thread(target=mythread, name='꽥꽥이', args=(0.3,))
    t1.start()
    t2.start()
    t3.start()
    main_thread = threading.currentThread()
    while True:
        tlist = threading.enumerate()
        if len(tlist) <= 2: break
        for t in tlist:
            if t is main_thread: continue
            print(t)
        time.sleep(1)

threading.Timer

  • 일정 시간 경과 후에 수행되는 실행, 즉 타이머 실행 표현

  • cancel() 메소드로 중지 할 수 있다.

  • Timer 는 타이머 스레드를 만들 때, 스레드가 시작하기 전에 실행을 취소하거나 일정 시간 마다 반복할 구문을 구현할 때 사용된다.

import threading
import time

def thread_test():
    for _ in range(5):
        print('python threading')

# 5초 후에 스레드 실행
t = threading.Timer(5, thread_test)
t.start()

# 2초 후에 cancle 메소드 실행 하므로 아무것도 실행되지 않고 종료
# time.sleep(2)
# t.cancel()

동기화

메소드 설명
threading.Event() 이벤트 객체를 생성
is_set() 내부 플래그의 값이 True 인 경우에만 True 리턴
set() 내부 플래그의 값을 True로 설정하며 대기중인 모든 스레드를 실행시킨다. 일단 플래그가 True가 되면 스레드가 wait()을 호출해도 스레드가 실행된다.
clear() 내부 플래그의 값을 False로 다시 설정한다. set() 을 호출하여 다시 내부 플래그의 값을 True로 설정 될 때까지 wait()을 호출한 스레드는 차단하도록 한다.
wait(timeout = None) 내부 플래그의 값이 True 가 될 때까지 블록 상태로 wait() 처리에 들어간 시점에서 내부 플래그의 값이 True이면 즉시 처리를 리턴하고 그렇지 않은 경우 다른 스레드가 set()를 호출하여 플래그 값을 True 로 설정하거나 옵션의 타임 아웃이 발생할 때까지 블록상태로 대기한다.
import threading

def counter(e):
    e.wait()
    for i in range(5):
        print(i)

if __name__ == '__main__':
    e = threading.Event()

    t1 = threading.Thread(target=counter, args=(e,))
    t1.start()

    for i in range(100, 105):
        print(i)
    
    # 대기중인 t1 스레드 실행
    e.set()

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함