쓰레드(Thread)

 

1. 쓰레드란?

  • **쓰레드(Thread)**는 프로그램 내에서 작업을 실행하는 최소 실행 단위.
  • 하나의 프로그램(프로세스)은 기본적으로 하나의 메인 쓰레드(fun main(0 메인함수)에서 실행되며, 이를 통해 모든 작업이 처리됨.
  • 추가 쓰레드를 생성하면 여러 작업을 동시에 처리할 수 있어 **동시성(Concurrency)**을 구현할 수 있음.

2. 쓰레드의 기본 개념

  1. 프로세스(Process):
    • 실행 중인 프로그램으로, 운영체제(OS)에서 메모리와 CPU를 할당받아 독립적으로 실행됨.
    • 각 프로세스는 독립된 메모리 공간(코드, 데이터, 힙, 스택)을 가짐.
  2. 쓰레드(Thread):
    • 프로세스 내에서 실행되는 작은 작업 단위.
    • 스택 메모리를 독립적으로 사용하지만, 힙 메모리(공유 자원)는 다른 쓰레드와 공유.
  3. 쓰레드의 메모리 구조:
    • 스택(Stack): 쓰레드마다 독립된 실행 컨텍스트를 저장.
    • 힙(Heap): 모든 쓰레드가 공유하는 메모리 공간.
    • 코드/데이터 영역: 프로그램의 실행 코드와 상수 저장.

3. 쓰레드의 특징

특징 설명
병렬 실행 여러 쓰레드가 동시에 실행 가능하여, 작업 처리 속도와 효율성을 높임.
스택 독립성 각 쓰레드는 독립된 스택 메모리를 가지므로, 실행 컨텍스트를 개별적으로 관리.
공유 자원 관리 쓰레드는 힙 메모리를 공유하므로, 공유 자원 접근 시 동기화(Synchronization)가 필요.
컨텍스트 스위칭 CPU가 여러 쓰레드 사이를 전환하며 실행. 전환 비용(오버헤드)이 발생.

4. 쓰레드의 필요성

  1. 동시성(Concurrency) 구현:
    • 하나의 작업을 여러 단위로 나누어 동시에 처리.
    • 예: UI 처리 중 파일 다운로드.
  2. 대기 시간 최소화:
    • 시간이 오래 걸리는 작업(네트워크 요청, 파일 입출력 등) 동안 다른 작업을 중단 없이 실행.
  3. 프로그램 효율성 향상:
    • 멀티코어 CPU에서 여러 쓰레드를 실행하면 자원을 효율적으로 활용 가능.

5. 쓰레드를 사용하는 주요 사례

  1. 게임:
    • 캐릭터의 움직임, 효과음, 사용자 입력 처리를 동시에 수행.
  2. 멀티미디어 애플리케이션:
    • 비디오 재생 중 오디오 출력과 자막 표시를 병렬로 실행.
  3. 네트워크 서버:
    • 여러 클라이언트 요청을 동시에 처리.
  4. 경쟁 환경:
    • 경마 프로그램처럼 여러 개체가 동시에 움직이고 결과를 경쟁.

6. 쓰레드의 구현

1) Kotlin에서 쓰레드 생성

fun main() {
    thread(start = true) {
        println("Thread 1: 실행 중")
    }

    thread(start = true) {
        println("Thread 2: 실행 중")
    }
}

2) 쓰레드 경쟁 예제

fun main() {
    thread(start = true) {
        for (i in 1..10) {
            println("Thread 1: $i")
            Thread.sleep(500) // 0.5초 대기
        }
    }

    thread(start = true) {
        for (i in 50..60) {
            println("Thread 2: $i")
            Thread.sleep(500) // 0.5초 대기
        }
    }
}

3) 쓰레드 동기화 문제 해결

  • 여러 쓰레드가 공유 자원을 동시에 접근할 경우, 데이터 충돌 문제 발생 가능.
  • 해결 방법: synchronized 키워드로 동기화 처리.
val lock = Any()
var sharedResource = 0

fun main() {
    thread(start = true) {
        synchronized(lock) {
            for (i in 1..5) {
                sharedResource++
                println("Thread 1: $sharedResource")
            }
        }
    }

    thread(start = true) {
        synchronized(lock) {
            for (i in 1..5) {
                sharedResource++
                println("Thread 2: $sharedResource")
            }
        }
    }
}

7. 쓰레드의 장단점

장점 단점
병렬 처리로 작업 처리 속도가 향상. 컨텍스트 스위칭으로 인한 성능 오버헤드 발생.
대기 시간이 긴 작업(I/O 작업)을 처리하면서 다른 작업을 실행 가능. 동기화 문제로 인해 데이터 충돌 및 데드락 발생 가능.
멀티코어 CPU 환경에서 성능 효율성을 극대화. 쓰레드 수가 많아지면 메모리 사용량 증가.

8. 추가 학습이 필요한 주제

  1. 코루틴 (Coroutine):
    • 쓰레드보다 가볍고 효율적인 비동기 프로그래밍 방식.
    • Kotlin의 대표적인 비동기 처리 도구.
  2. 동기화(Synchronization):
    • 공유 자원 접근 시 발생하는 문제를 해결하기 위한 기술.
    • Mutex, Semaphore, Volatile 등.
  3. 컨텍스트 스위칭(Context Switching):
    • 쓰레드 간 전환 시 발생하는 비용과 효율성 최적화 방법.
  4. 멀티쓰레드 디버깅:
    • 복잡한 쓰레드 환경에서의 오류 해결 방법.
  5. Reactive Programming:
    • 비동기 데이터를 처리하는 프로그래밍 패러다임. (Ex: RxJava, Project Reactor)

9. 결론

쓰레드는 동시성과 병렬성을 구현하기 위한 강력한 도구입니다. 하지만 쓰레드를 잘못 설계하면 데이터 충돌, 데드락 등 복잡한 문제가 발생할 수 있습니다. 쓰레드의 한계를 보완하기 위해 코루틴 같은 최신 기술도 함께 학습하면 더욱 효율적인 프로그래밍이 가능합니다. 

'CS ( Computer Science ) > 운영 체제 (Operating Systems)' 카테고리의 다른 글

[OS] 자원 관리  (0) 2025.02.20
[OS] 코루틴  (0) 2025.02.19
[OS] 비동기 프로그래밍  (0) 2025.02.18
[OS] 프로세스와 쓰레드  (0) 2024.11.24

+ Recent posts