• 티스토리 홈
  • 프로필사진
    소쩍소쩍이
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
소쩍소쩍이
  • 프로필사진
    소쩍소쩍이
    • 분류 전체보기 (89)
      • 파이썬 (18)
        • 문제 및 예제 (8)
      • PySide6 (24)
        • Signal & Slot (6)
        • Layout (8)
        • Model & View (3)
        • File (4)
        • Resource (3)
      • Server - Client (17)
        • GUI 채팅 (1)
      • MySQL (4)
      • 리눅스 (5)
      • 아두이노 (0)
      • 일지 (20)
  • GitHub
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    # Home
    # 공지사항
    #
    # 태그
    # 검색결과
    # 방명록
    • 스레드 개념과 기초 사용법
      2026년 06월 23일
      • 소쩍소쩍이
      • 작성자
      • 2026.06.23.:39

      스레드란?

      스레드는 프로그램 안의 작은 실행 흐름이다.

      스레드 = 하나의 프로그램 안에서 실행되는 별도의 작업 흐름

      스레드를 사용하면 서버 프로그램이 여러 개 생기는 것이 아니라, 하나의 서버 프로그램 안에서 여러 작업 흐름이 동시에 움직이게 된다.

       

      하나의 서버 프로그램
      ├── 메인 흐름: 새 클라이언트 접속을 기다림
      ├── 스레드 1: 클라이언트 A의 메시지 처리
      ├── 스레드 2: 클라이언트 B의 메시지 처리
      └── 스레드 3: 클라이언트 C의 메시지 처리

       

      용어 쉬운 설명
      프로세스 실행 중인 프로그램 하나
      스레드 프로그램 안에서 움직이는 작업 흐름
      메인 스레드 프로그램이 처음 시작될 때 기본으로 실행되는 흐름
      작업 스레드 특정 작업을 따로 처리하기 위해 추가로 만든 흐름

       

      채팅 서버에 스레드가 필요한 이유

      스레드를 사용하는 것은 단순히 속도를 높이기 위해서가 아니다. 핵심은 기다리는 작업을 분리하는 것이다.

      각 클라이언트가 언제 메시지를 보낼지 알 수 없기 때문에, 클라이언트마다 별도 스레드를 두어 각자 기다리게 만드는 것이 중요하다.

       

      역할 하는 일
      메인 스레드 새 클라이언트 접속을 계속 받음 (accept() 반복)
      클라이언트 처리 스레드 특정 클라이언트의 메시지를 기다리며 처리

       

      핵심
      스레드는 여러 클라이언트를 동시에 처리하기 위해 사용한다.
      특히 recv()처럼 기다리는 작업을 클라이언트마다 분리할 수 있다는 점이 중요하다.

       

      비유와 기본 형태

      요리사로 비유하기

      순차 실행은 요리사 한 명이 A 요리를 끝낸 뒤에 B 요리를 시작하는 것과 같다.

      스레드 실행은 A 요리와 B 요리를 동시에 진행하는 것과 비슷하다. A 냄비에 불을 올리고 기다리는 시간 동안 B 재료를 손질하는 느낌으로 이해할 수 있다.

       

      주방 비유 서버 역할
      요리사 한 명이 순서대로 요리 순차 실행 — 한 클라이언트가 끝날 때까지 대기
      여러 냄비를 동시에 올림 스레드 실행 — 각 클라이언트를 독립 흐름으로 처리
      불 올리고 기다리는 시간 recv() 대기 — 이 시간에 다른 클라이언트 처리 가능
      냄비마다 다른 요리 진행 클라이언트마다 다른 스레드가 처리

       

      기본 형태

      파이썬에서 스레드를 사용할 때는 threading 모듈을 사용한다.

      import threading
       
      def work():
          print("스레드에서 실행할 작업입니다.")
       
      thread = threading.Thread(target=work)   # 스레드 객체 생성 — 아직 실행 안 됨
      thread.start()                           # 스레드 실제 시작

       

      코드 의미
      threading.Thread(target=work) 새 스레드 객체를 만든다. work 함수를 실행할 준비를 한다
      target=work 스레드가 실행할 함수 이름을 지정한다
      thread.start() 스레드를 실제로 시작한다. 이 줄 이후 함수가 별도 흐름에서 실행된다

       

      자주 하는 실수 - target에 괄호 붙이기

      자주 하는 실수는 target에 함수 이름 뒤 괄호를 붙이는 것이다.

      # 잘못된 형태 — work()가 바로 호출되고, 그 반환값(None)이 target에 전달됨
      threading.Thread(target=work())
       
      # 올바른 형태 — work 함수 자체를 스레드에 넘기고, 스레드가 나중에 실행
      threading.Thread(target=work)

      target=work()로 작성하면 스레드를 만드는 그 줄에서 work()가 바로 실행되어 버린다. 에러 메시지가 바로 나오지 않는 경우도 있어서 왜 스레드가 예상대로 동작하지 않는지 헷갈릴 수 있다.

      target 뒤에는 항상 괄호 없이 함수 이름만 작성한다. 나중에 handle_client(client_socket)처럼 인자가 있는 함수를 넘길 때도 같은 원리로 생각하면 된다.

      중요
      target=work()는 함수를 바로 실행하는 형태이다.
      스레드에 함수 자체를 넘기려면 target=work처럼 괄호 없이 작성해야 한다.

       

      스레드 실행 순서

      ① threading.Thread(target=함수) — 스레드 객체 생성 (아직 실행 안 됨)
              ↓
      ② thread.start()                — 스레드 실제 시작
              ↓
      ③ 메인 흐름과 스레드 흐름이 동시에 진행됨
              ↓
      ④ thread.join() (선택)          — 스레드가 끝날 때까지 메인 흐름이 기다림

      join()은 "이 스레드가 완전히 끝날 때까지 기다려라"라는 의미이다.

      다중 접속 채팅 서버에서는 스레드가 클라이언트 연결이 끊길 때까지 계속 실행되므로 join()을 쓰지 않는 경우도 많다.

       

      순차 실행과 스레드 실행 비교

      순차 실행의 경우

      import time
       
      def work(name):
          for i in range(3):
              print(f"{name} 작업 중: {i + 1}")
              time.sleep(1)    # 1초 기다림 — 클라이언트가 메시지를 보낼 때까지 기다리는 상황과 비슷
       
      work("A")
      work("B")
       
      print("모든 작업이 끝났습니다.")

      순차 실행에서는 A의 작업이 모두 끝난 뒤 B의 작업이 시작된다.

       

      스레드로 바꿔서 실행하기

      import threading
      import time
       
      def work(name):
          for i in range(3):
              print(f"{name} 작업 중: {i + 1}")
              time.sleep(1)
       
      thread_a = threading.Thread(target=work, args=("A",))   # 스레드 생성 — 아직 실행되지 않음
      thread_b = threading.Thread(target=work, args=("B",))   # 스레드 생성 — 아직 실행되지 않음
       
      thread_a.start()   # A 스레드 시작 — 독립 흐름으로 실행 시작
      thread_b.start()   # B 스레드 시작 — 독립 흐름으로 실행 시작
       
      thread_a.join()    # A 스레드가 끝날 때까지 메인 흐름이 기다림
      thread_b.join()    # B 스레드가 끝날 때까지 메인 흐름이 기다림
       
      print("모든 작업이 끝났습니다.")

      스레드를 사용하면 A가 모두 끝난 뒤 B가 시작되는 것이 아니라 두 작업의 출력이 섞여 나타난다.

       

      args로 스레드 함수에 값 전달하기

      work(name) 함수는 name이라는 인자가 필요하다. 스레드에서 이 값을 전달하려면 args를 사용한다.

      args는 반드시 튜플 형태여야 한다.

      # 잘못된 형태 — 튜플이 아니라 문자열로 전달됨, 예상치 못한 동작 가능
      args=("A")
       
      # 올바른 형태 — 값이 하나여도 쉼표를 붙여 튜플로 만듦
      args=("A",)
      
      # 인자가 두 개인 경우 — 쉼표 없어도 튜플
      args=(client_socket, client_address)
       
      # 인자가 하나인 경우 — 쉼표 필수
      args=(client_socket,)
      주의
      args에 값이 하나만 들어갈 때는 반드시 쉼표를 붙여야 한다.
      args=("A",)처럼 작성해야 튜플로 인식된다.

       

      join() - 스레드가 끝날 때까지 기다리기

      import threading
      import time
       
      def work(name):
          for i in range(3):
              print(f"{name} 작업 중: {i + 1}")
              time.sleep(1)
       
      thread_a = threading.Thread(target=work, args=("A",))   
      thread_b = threading.Thread(target=work, args=("B",))  
       
      thread_a.start()   
      thread_b.start()   
       
      work("메인 스레드") # 추가
       
      thread_a.join()    # join 제거 후 테스트
      thread_b.join()    # join 제거 후 테스트
       
      print("모든 작업이 끝났습니다.")

      join()은 해당 스레드가 완전히 끝날 때까지 메인 흐름이 그 자리에서 기다리게 한다.

       

      정리
      스레드는 하나의 프로그램 안에서 실행되는 별도의 작업 흐름이다.

      채팅 서버에서는 클라이언트마다 독립적인 스레드를 만들어 메시지를 기다리게 할 수 있다.

      target에는 함수 이름만 전달하고, 인자가 필요한 경우 args를 사용한다.
      스레드가 끝날 때까지 기다려야 하는 경우에는 join()을 사용할 수 있다.

      'Server - Client' 카테고리의 다른 글

      접속자 목록 관리  (0) 2026.06.23
      스레드로 클라이언트 처리  (0) 2026.06.23
      여러 클라이언트 접속 구조  (0) 2026.06.23
      1:1 터미널 채팅 완성하기  (0) 2026.06.22
      반복 송수신과 종료 처리  (0) 2026.06.22
      다음글
      다음 글이 없습니다.
      이전글
      이전 글이 없습니다.
      댓글
    조회된 결과가 없습니다.
    스킨 업데이트 안내
    현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
    ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
    목차
    표시할 목차가 없습니다.
      • 안녕하세요
      • 감사해요
      • 잘있어요

      티스토리툴바