OS - Threads

윤형·2025년 4월 28일

Operation System

목록 보기
5/9
post-thumbnail

Thread

하나의 프로세스 내에서 독립적으로 실행되는 작업 단위.

<특징>

  • 공유 자원 : 같은 프로세스 메모리, 파일 핸들을 공유한다.
  • 경량 생성 : 프로세스 생성보다 빠르고 리소스 소모가 적다.

Thread 사용하는 이유

  • 가벼움 : 프로세스를 새로 만드는것은 매우 무거운 작업인데, thread생성은 쉽고 가볍다.
  • 병렬성 : 여러 작업을 동시에 처리할 수 있다.(반응성이 좋아짐)
  • 코드 간소화 : 코드를 더 단순하게 할 수 있고, 효율성을 높일 수 있다.
  • 응답성 향상 : UI가 멈추지 않고 백그라운드 작업을 수행할 수 있다.(예: 타이핑, 철자 검사 동시에 진행)

MultiThread

  • 스레드는 같은 주소 공간을 사용하기 때문에 서로 공유하기가 수월하다.
  • 또한 프로세스를 또 만드는 것 보다 스레드를 확장하는게 더욱 경제적이다.

single Thread

  • 특징

    • 모든 자원이 1개의 실행 흐름만 사용한다.
  • 장점

    • 간단하고 동기화의 문제가 없다.
  • 단점

    • 병렬성이 없다. -> CPU코어를 효율적으로 활용하지 못한다.

다중 Thread

  • 특징
    • 레지스터와 스택은 각 스레드 마다 독립적으로 갖는다.
    • 코드, 데이터, 파일은 공유한다.

  • 스레드가 많으면 병렬처리가 가능하다.
  • single코어에서는 병렬처리가 보이게끔 context switching을 이용해 처리하지만,
  • core의 수가 많아지면 스레드 개수에 따라 정말로 병렬적으로 처리할 수 있다.

Multithreading Models

1. Many-to-One Model

다수의 사용자 수준 스레드를 단일 커널 스레드에 매핑한다. 스레드 관리가 사용자 공간에서 이루어지기 때문에 경량화 된다.

<예시> : Solaris Green Threads, GNU Portable Threads

<장점>

  • 생성 및 context switch 비용이 낮다.
  • 커널 개입 없이 스레드 라이브러리가 직접 스케줄링을 처리한다. (system call을 사용한 커널 모드 전환이 필요 없음.)
  • 커널 모드 전환이 필요없는 이유는 user thread들 끼리는 사용자 모드에서 현재 스레드의 레지스터, 스택등을 저장하고 context switching을 하기 때문이다.

<단점>

  • 한 therad가 블로킹이 되면, 전체 프로세스가 차단되는 단일코어 한계가 존재한다.

2. One-to-One Model

각 사용자 스레드를 개별 커널 스레드에 1:1 매핑한다.
병렬성과 멀티코어 활용이 가능하다.

<예시> : Window NT/XP/2000, Linux, Solaris 9 이상

<장점>

  • 안정성 : system call 블로킹이 다른 스레드에 영향을 미치지 않는다.

<단점>

  • 커널 스레드 생성 오버헤드로 인해 자원 소모가 많이 든다.

3. Many-to-Many Model

사용자 스레드와 커널 스레드를 유연하게 매핑한다. 동적 스레드 풀 관리로 효율성을 극대화 한다.
OS가 필요한 커널 스레드를 생성할 수 있다.

<예시> : Solaris 9 이전 버전들, Window ThreadFiber pakage등

<장점>

  • 동시에 여러 커널 스레드를 사용해, 병렬성을 보장한다.

<단점>

  • 복잡한 스케줄링 알고리즘이 필요하다.

4. Two-level Model

Many-to-Many모델을 확장해 특정 사용자 스레드는 직접 kernel 스레드에 매핑한다. (하이브리드 형태)

<예시> : IRIX, HP-UX, Solaris 8....등

<장점>

  • 중요한 스레드에 우선순위를 부여할 수 있다.
  • 일반 스레드는 동적 매핑으로 오버헤드가 감소한다.

<단점>

  • 하이브리드 구조로 복잡성이 증가한다.

추가적으로 보통 웹서버는 Many-to-Many모델을 통해 확장성 위주로 구현을 하고, 게임같은 경우에는 One-to-One모델로 병렬성을 활용해 구현을 한다.

Thread Library

Thread Library는 프로그래머가 스레드를 생성하고 관리할 수 있도록 API를 제공하는 소프트웨어 라이브러리다.
개발자는 손쉽게 스레드를 만들고, 실행하고, 동기화하는 등의 작업을 수행할 수 있다.

  • User Space에서 라이브러리
    : 스레드 관리가 운영체제 커널과 별개로 사용자 영역에서 이루어짐.
    : context switching이나 스케줄링 등 대부분의 작업이 라이브러리 내부에서 처리되어 커널 개입이 적다.

  • Kernel Level에서 운영체제가 지원하는 라이브러리
    : 스레드 관리 및 스케줄링이 운영체제 커널에서 직접 이루어 진다.
    : 각 스레드는 커널에 의해 관리되므로, 멀티코어 환경에서 진정한 병렬 실행이 다능하다.

Threading Issue

멀티스레드를 사용할 시 발생할 수 있는 주요 문제점과 해결방안에 대해서 알아보도록 하자.

1. fork()와 exec()의 의미론

  • 문제점 : 멀티스레드 프로세스에서 fork()시스템 호출 시, 모든 스레드를 복제할지 아니면 호출한 스레드만 복제할지 명확하지 않는다.
    • exec()가 fork()이후 실행이 되면, 모든 스레드가 교체되기 때문에 복제된 스레드가 의미가 없어짐.
  • 해결법 : fork() 후 exec()을 호출하지 않는 경우, 호출 스레드만 복제하는 방식이 일반적이다.

2. Thread cancelled

목적 : 실행중인 스레드를 강제로 종료시키는 메커니즘.

방식특징예시
Asynchronous 취소즉시 스레드 종료한다.
누수 또는 데이터 불일치 리스크
웹 브라우저 페이지 로딩 종료
Deferred(지연) 취소스레드가 안전한 취소 지점에서
주기적으로 종료 여부 확인
병렬 데이터베이스 쿼리 중단

3. Signal Handiling

목적 : 시그널을 어떤 스레드에 전달할 지 결정해야 한다. (시그널: 긴급 알림 개념)

  • 동기 시그널 : 오류를 발생시킨 스레드에게 전달.

  • 비동기 시그널 : 임의의 스레드 또는 모든 스레드에 전달.

  • 시그널이 처리되는 과정

    • 특정 이벤트에 의해 시그널이 발생한다.
    • 시그널이 프로세스로 전달된다.
    • 시그널이 처리된다.
  • 처리 Option

    • 해당 시그널이 적용되는 스레드한테만 전달(오류 발생 시 그 스레드에 오류 시그널 전달)
    • 프로세스 내에 모든 스레드에게 시그널을 전달
    • 프로세스 내에 특정 스레드에게 시그널을 전달(미리 설정)
    • 프로세스의 모든 시그널을 수신하도록 특정 스레드를 지정한다.(시그널 전담)
  • 시그널 종류

    • 동기적 시그널 : 스레드가 직접적으로 발생시킨 이벤트 때문에 발생하는 시그널 (오류 발생이 대표적이다.)
    • 비동기적 시그널 : 프로세스나 특정 스레드 외부의 다른 이벤트 때문에 발생하는 시그널. ( 일부 혹은 모든 스레드에 전달 가능)
  • Unix환경에서 시그널 처리

    • 각 스레드가 시그널을 받을 지 말지(block) 결정할 수 있음, 보통 시그널 받기로한 스레드중에서 가장 먼저 준비된 스레드가 받아서 처리한다,
    • kill(pid, signal) - pid를 가진 프로세스에게 보낸다.(전체 전송)
    • pthread_kill(tid, signal) - 스레드ID(tid)를 가진 특정 스레드에 보낸다.
  • Window 환경에서 시그널 처리

    • 시그널 개념을 사용하지 않는다.
    • APC : 대신 APC를 사용해서 유닉스의 시그널과 비슷한 비동기적인 알림 및 처리를 구현한다.

4. Thread Pools

목적 : 스레드 생성/삭제 오버헤드를 줄이고 자원 사용량을 제한한다.

  • 작동 방식
    1. 미리 생성된 스레드 풀에서 작업을 할당받아 사용한다.
    2. 작업 완료 후 풀에 반환되어 재사용한다.
  • 장점
    • 응답 시간이 단축된다.(스레드 생성시간 제거)
    • 시스템 과부화 방지(풀 사이즈 제한)
    • ex) 웹 서버가 동시 요청을 Pool로 관리한다.

5. Therad Specific Data

필요성 : 스레드가 고유한 데이터를 독립적으로 관리해야 할 수 있게 해준다.

  • 여러 스레드는 메모리 공간을 공유한다. -> 전역변수와 같은 데이터는 여러 스레드가 동시에 수정하려고 하면 Race Condition이 발생할 수 있다.
  • 따라서 각 스레드마다 별도의 데이터를 따로 가질 수 있게 해준다.

profile
제가 관심있고 공부하고 싶은걸 정리하는 저만의 노트입니다.

0개의 댓글