본문 바로가기

IT 공부/운영체제

5-3. 스레드 주소 공간과 컨텍스트

3-1. 스레드 주소 공간

스레드 주소 공간

스레드가 실행 중에 사용하는 메모리 공간

  • 스레드의 코드, 데이터, 힙, 스택 영역

프로세스의 주소 공간 내에 형성

스레드 주소 공간의 요소들

스레드 사적 공간

  • 스레드 코드(Thread code)
  • 스레드 로컬 스토리지(Thread local storage)

스레드 사이의 공유 공간

  • 프로세스의 코드
  • 프로세스의 데이터 공간(로컬 스토리지 제외)
  • 프로세스의 힙 영역

스레드 주소 공간 사례

3-2. 스레드 주소 공간에 대한 설명

스레드 코드 영역

스레드가 실행할 작업의 함수

  • 프로세스의 코드 영역 사용

스레드는 프로세스의 코드 영역에 있는 다른 모든 함수 호출 가능

스레드 데이터 영역

스레드가 사용할 수 있는 데이터 공간

  • 프로세스의 데이터 영역 사용

2개의 공간으로 구분

  • 개별 스레드 전용 전역 변수 공간(스레드 로컬 스토리지)
    • static_thread와 같은 특별한 키워드로 선언, 컴파일러에 의해 결정
  • 프로세스에 선언된 모든 전역 변수들은 모든 스레드에 의해 공유
    • 스레드 사이의 통신 공간으로 유용하게 사용

스레드 힙

모든 스레드가 동적 할당받는 공간, 프로세스의 힙 공간 사용

스레드에서 malloc()를 호출하면 프로세스의 힙 공간에서 할당받음

스레드 스택

스레드가 생성될 때마다 프로세스의 사용자 스택의 일부분을 할당 받음.

스레드가 시스템 호출로 커널에 집입할 때, 커널 내에 프로세스에게 할당한 커널스택에서 스레드를 위한 스택 할당

예시
과정
과정 2

3-3. 스레드 상태

스레드 일생

- 스레드는 생성, 실행, 중단, 실행, 소멸의 여러 상태를 거치면서 실행된다.

- 스레드 상태는 TCB에 저장된다.

- 스레드 상태

  • 준비 상태(Ready) - 스레드가 스케줄 되기를 기다리는 상태
  • 실행 상태(Running) - 스레드가 CPU에 의해 실행 중인 상태
  • 대기 상태(Blocked) - 스레드가 입출력을 요청하거나 sleep()과 같은 시스템 호출로 인해 중단된 상태
  • 종료 상태(Terminated) - 스레드가 종료된 상태

3-4. 스레드 운용(Operation)

응용 프로그램이 스레드에 대해 할 수 있는 운용의 종류

- 스레드 생성

  • 스레드는 스레드를 생성하는 시스템 호출이나 라이브러리 함수를 호출하여 다른 스레드 생성 가능
  • 프로세스가 생성되면 자동으로 main 스레드 생성

- 스레드 종료

  • 프로세스 종료와 스레드 종료의 구분 필요
  • 프로세스 종료
    • 프로세스에 속한 아무 스레드가 exit() 시스템 호출을 부르면 프로세스 종료(모든 스레드 종료)
    • 메인 스레드의 종료(C 프로그램에서 main()함수 종료) - 모든 스레드도 함께 종료
    • 모든 스레드가 종료하면 프로세스 종료
  • 스레드 종료
    • pthread_exit()와 같이 스레드만 종료하는 함수 호출 시 해당 스레드만 종료
    • main() 함수에서 pthread_exit()을 부르면 main 스레드만 종료

스레드 조인

  • 스레드가 다른 스레드가 종료할 때까지 대기
    • 주로 부모 스레드가 자식 스레드의 종료 대기
  • 스레드 양보
    • 스레드가 자발적으로 yield()와 같은 함수 호출을 통해 스스로 실행을 중단하고 다른 스레드를 스케줄하도록 요청

3-5. 스레드 조인

- 스레드가 다른 스레드의 종료를 기다리는 행위

3-6. 스레드 컨텍스트

스레드의 실행중인 상태 정보

- 스레드의 실행중인 상태 정보

  • CPU 레지스터들의 값
    • PC, SP, 데이터/상태 레지스터 등
  • TCB에 저장됨

- PC 레지스터

  • 실행 중인 코드 주소

- SP 레지스터

  • 실행 중인 함수의 스택 주소

- 상태 레지스터

  • 현재 CPU의 상태 정보

- CPU에는 수십 개의 레지스터가 있음

  • 이들만 저장해두었다가 필요할 때 CPU에 복귀하면, 이전에 실행하던 상태로 돌아갈 수 있음.

3-7. 스레드 제어 블록

스레드 제어 블록, TCB(Thread Control Block)

- 스레드를 실행 단위로 다루기 위해 스레드에 관한 정보를 담은 구조체

  • 스레드 엔터티(Thread entity), 스케줄링 엔터티(scheduling entity)라고도 불림

- 커널 영역에 만들어지고, 커널에 의해 관리

  • 스레드가 생성될 때 커널에 의해 만들어짐
  • 스레드가 소멸되면 함께 사라짐

3-8. 스레드 TCB, 그리고 PCB의 관계

프로세스 : 스레드들이 생기고 활동하는 자원의 컨테이너

TCB들은 링크드 리스트로 연결

3-9. 준비 리스트와 블록 리스트

준비 리스트

- 준비 상태에 있는 스레드들의 TCB를 연결하여 관리하는 링크드 리스트

 - 스레드 스케줄링은 준비 리스트의 TCB들 중 하나 선택

블록 리스트

- 블록 상태에 있는 스레드들의 TCB를 연결하여 관리하는 링크드 리스트

3-10. 스레드 컨텍스트 스위칭

스레드 컨텍스트 스위칭

- 현재 실행중인 스레드를 중단시키고, 다른 스레드에게 CPU 할당

  • 스레드 스위칭이라고도 부름
  • 현재 CPU 컨텍스트를 TCB에 저장하고, 다른 TCB에 저장된 컨텍스트를 CPU에 적재

3-11. 스레드 스위칭이 발생하는 4가지 경우

- 스레드 스위칭이 발행하는 4가지 경우

  1. 스레드가 자발적으로 다른 스레드에게 양보
    • yield() 등의 시스템 호출(혹은 라이브러리 호출)을 통해
  2. 스레드가 시스템 호출을 실행하여 블록되는 경우
    • read(), sleep(), wait() 등 I/O가 발생하거나 대기할 수 밖에 없는 경우
  3. 스레드의 타임 슬라이스(시간 할당량)를 소진한 경우
    • 타이머 인터럽트에 의해 체크
  4. I/O장치로 부터 인터럽트가 발생한 경우
    • 현재 실행중인 스레드보다 더 높은 우선순위의 스레드가 I/O작업을 끝낸 경우 등

상황에 따라 운영체제에 따라 이들 4가지 경우 외에도 스레드 스위칭이 일어날 수도 있고, 아닐 수도 있음.

3-12. 스레드 스위칭 과정(스레드 A에서 스레드 B로)

1) CPU 레지스터 저장 및 복귀

- 현재 실행 중인 스레드 A의 컨텍스트를 TCB-A에 저장

- TCB-B에 저장된 스레드 B의 컨텍스트를 CPU에 적재

  • CPU는 스레드 B가 이전에 중단된 위치에서 실행 재개 가능
  • SP 레지스터를 복귀함으로서 자신의 이전 스택을 되찾게 된다.
    • 스택에는 이전 중단될 때 실행하던 함수의 매개변수나 지역변수들이 그대로 저장되어 있다.

2) 커널 정보 수정

- TCB-A와 TCB-B에 스레드 상태 정보와 CPU 사용 시간 등 수정

- TCB-A를 준비 리스트나 블록 리스트로 옮김

- TCB-B를 준비 리스트에서 분리

3-13. 컨텍스트 스위칭 오버헤드

컨텍스트 스위칭에는 어떤 부담(오버헤드)이 있는가?

- 컨텍스트 스위칭은 모두 CPU 작업 -> CPU 시간 소모

- 컨텍스트 스위칭의 시간이 길거나, 잦은 경우 컴퓨터 처리율 저하

구체적인 컨텍스트 스위칭 오버헤드

- 동일한 프로세스 내 다른 스레드로 스위칭 되는 경우

  1. 컨텍스트 저장 및 복귀
    • 현재 CPU의 컨텍스트(PC, PSP, 레지스터) TCB에 저장
    • TCB로부터 실행할 스레드의 스레드 컨텍스트를 CPU에 복귀
  2. TCB 리스트 조작(준비, 블록 리스트 등)
  3. 캐시 플러시와 채우기 시간

- 다른 프로세스의 스레드로 스위칭하는 경우

  • 다른 프로세스로 교체되면, CPU가 실행하는 주소 공간이 바뀌는 큰 변화로 인한 추가적인 오버헤드 발생
  1. 추가적인 메모리 오버헤드
    • 시스템 내에 현재 실행 중인 프로세스의 매팅 테이블을 새로운 프로세스의 매핑 테이블로 교체
  2. 추가적인 캐시 오버헤드
    • 프로세스가 바뀌기 때문에, 현재 CPU 캐시에 담긴 코드와 데이터를 무력화 시킴
    • 새 프로세스의 스레드가 실행을 시작하면 CPU 캐시 미스 발생, 캐시가 채워지는데 상당한 시간 소요