땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • ㅗ
  • 이것이 리눅스다 with Rocky Linux9
  • I
  • E
  • D

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원

땅지원's Personal blog

Python Thread
Backend/Python

Python Thread

2021. 12. 28. 20:04

OS에서 어떤 실행 프로그램이 실행된다는 것은 CPU, 메모리, SSD와 같은 컴퓨터 자원을 사용한다

OS가 프로그램들이 실행될 수 있도록 부여하는 공간을 프로세스 라고 한다.

 

프로세스에는 응용 프로그램이 있다. OS 입장에서 프로세스에 있는 객체를 Thread라고 한다.

 

Thread

  • 프로그램이라고 부르는 것은 OS위에서 동작한다
  • 프로그램이 메모리에 올라가서 실행 중인 것을 프로세스라고 부른다
  • 프로세스의 실행 단위를 스레드 라고 한다.
  • 프로세스는 최소 하나 이상의 스레드를 가지며 경우에 따라 여러 스레드를 가질 수 있다(멀티스레드)

우리가 윈도우를 사용할 때 메신저도 사용하고 게임도 하고 문서작성도 하고 인터넷도 사용한다

윈도우는 동시에 실행되는 여러 프로그램들을 잘 관리해야하는데 이런 작업을 스케줄링이라고 한다.

운영체제는 스케쥴링의 단위로 스레드를 사용한다

 

threading 모듈 사용

파이썬 기본 모듈로 thread, threading 모듈이 있으며 PyQt 의 QThread도 있다

#threading 모듈 사용

import threading
import time


class Worker(threading.Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name            # thread 이름 지정

    def run(self):
        print("sub thread start ", threading.currentThread().getName())
        time.sleep(3)
        print("sub thread end ", threading.currentThread().getName())


print("main thread start")
for i in range(5):
    name = "thread {}".format(i)
    t = Worker(name)                # sub thread 생성
    t.start()                       # sub thread의 run 메서드를 호출

print("main thread end")
main thread start
sub thread start  thread 0
sub thread start  thread 1
sub thread start  thread 2
sub thread start  thread 3
sub thread start  thread 4
main thread end
sub thread end  thread 0
sub thread end  thread 1
sub thread end sub thread end  thread 2
 thread 4
sub thread end  thread 3

메인 스레드가 5개의 서브 스레드를 생성하고 start 메소드를 호출하여  Worker 클래스의 run() 메소드 호출

서브 스레드들은 0,1,2,3,4 순으로 실행됐지만 종료 순서는 조금 다르다

데몬 스레드

데몬(daemon) 스레드는 메인 스레드가 종료될 때 자신의 실행 상태와 상관없이 종료되는 서브 스레드 의미

 

threading 모듈을 사용해서 메인 스레드가 서브 스레드를 생성하는 경우 메인 스레드는 서브 스레드가 모두 종료될 때까지 기다렸다가 종료하게 된다. 하지만 실제 프로그래밍을 하다보면 경우에 따라 메인 스레드가 종료되면 모두 서브스레드가 동작 여부에 상관없이 종료되어야 하는 경우가 많다. 이때 서브 스레드 들은 데몬 스레드로 만들어져야 한다.

#데몬 스레드 

import threading
import time


class Worker(threading.Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name            # thread 이름 지정

    def run(self):
        print("sub thread start ", threading.currentThread().getName())
        time.sleep(3)
        print("sub thread end ", threading.currentThread().getName())


print("main thread start")
for i in range(5):
    name = "thread {}".format(i)
    t = Worker(name)                # sub thread 생성
    t.daemon = True
    t.start()                       # sub thread의 run 메서드를 호출

print("main thread end")
main thread start
sub thread start  thread 0
sub thread start  thread 1
sub thread start  thread 2
sub thread start  thread 3
sub thread start  thread 4
main thread end

실행 결과를 확인해보면 메인 스레드가 종료되면서 time.sleep(3)에 의해 대기 상태에 있던 서브 스레드들은 끝나기 전에 모두 종료된 것을 확인할 수 있다.

 

Fork & Join

Fork : 메인 스레드가 서브 스레드를 생성 하는 것

Join : 모든 스레드가 작업을 마칠 때까지 기다리는 것, 보통 데이터를 여러 스레드를 통해서 병렬로 처리한 후 그 값들을 다시 모아서 순차적으로 처리해야할 필요가 있을 때 분할한 데이터가 모든 스레드에서 처리될 때까지 기다렸다가 메인 스레드가 다시 추후 작업을 하는 경우에 사용한다

import threading
import time


class Worker(threading.Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name            # thread 이름 지정

    def run(self):
        print("sub thread start ", threading.currentThread().getName())
        time.sleep(5)
        print("sub thread end ", threading.currentThread().getName())


print("main thread start")

t1 = Worker("1")        # sub thread 생성
t1.start()              # sub thread의 run 메서드를 호출

t2 = Worker("2")        # sub thread 생성
t2.start()              # sub thread의 run 메서드를 호출

t1.join()
t2.join()

print("main thread post job")
print("main thread end")
main thread start
sub thread start  1
sub thread start  2
sub thread end  2
sub thread end  1
main thread post job
main thread end

결과를 보면 t1, t2 스레드가 종료된 후 'main thread post job'이 출력된 것을 확인할 수 있다

참고로 앞의 예에서는 메인스레드가 모든 실행을 완료한 후 서브스레드가 종료될 때까지 기다렸지만 이 예제에서는 join( ) 메서드가 호출되는 지점에서 기다린다는 차이가 있다

 

'Backend > Python' 카테고리의 다른 글

Web Framework Django 시작하기(1) - 프로젝트 생성  (0) 2022.01.08
Python Multithread vs Multiprocessing  (0) 2021.12.29
Python Flask 웹 페이지 제작(3) - Form  (0) 2021.12.21
Python Flask 웹 페이지 제작(2) - Jinja2 템플릿  (2) 2021.12.21
Python Flask 웹 페이지 제작(1) - 구조, Route  (0) 2021.12.21
    'Backend/Python' 카테고리의 다른 글
    • Web Framework Django 시작하기(1) - 프로젝트 생성
    • Python Multithread vs Multiprocessing
    • Python Flask 웹 페이지 제작(3) - Form
    • Python Flask 웹 페이지 제작(2) - Jinja2 템플릿
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바