프로세스의 문제점
프로세스의 문제점
1) 프로세스 생성의 큰 오버헤드
- 프로세스 생성
- 프로세스를 위한 메모리 할당 - 부모프로세스로부터 복사
- PCB 생성, 매핑 테이블(페이지 테이블) 생성 등
2) 프로세스 컨텍스트 스위칭의 큰 오버헤드
- 컨텍스트 스위칭
- CPU가 참고할 매핑 테이블(페이지 테이블) 전화네 따른 지연 시간 등
- CPU 레지스터들을 프로세스 컨텍스트에 저장, 새 프로세스 컨텍스트를 CPU로 옮기는 시간
- CPU 캐시에 새로운 프로세스의 코드와 데이터가 채워지는데 걸리는 시간 등
3) 프로세스 사이 통신의 어려움
- 프로세스들은 완전한 독립적인 주소 공간을 가지고 있음
- 프로세스가 다른 프로세스의 메모리에 접근 불가
- 프로세스 사이의 통신을 위한 제3의 방법 필요
- 커널 메모리나 커널에 의해 마련된 메모리 공간을 이용하여 데이터 송수신 (신호, 소켓, 메시지 큐, 세마포, 공유메모리, 메모리맵 파일 등)
- 이 방법들은 코딩도 어렵고, 느린 실행 속도, 운영체제 호환성 부족
스레드의 개념
스레드의 출현 목적
** 프로세스를 사용하는 문제점 해결을 위해 고안
- 프로세스보다 더 작은 실행 단위 필요
- 실행 단위란 운영체제의 스케줄링 단위
- 스레드를 가벼운 프로세스(light- weight process, LWP)라고 부름
- 프로세스의 생성 및 소멸에 따른 오버헤드 감소
- 빠른 컨텍스트 스위칭
- 프로세스의 복잡한 통신 방법, 느린 실행 속도, 코딩의 어려움 해소
프로세스와 스레드 관리
멀티스레딩과 concurrency, parallelism
concurrency(동시성)
- 1개의 CPU에서 2개 이상의 스레드가 동시에 실행 중인 상태
- 입출력 때문에 중단하면 다른 스레드 실행
- 타임 슬라이스 단위로 CPU를 사용하도록 번갈아 스레드 실행
parallelism
- 2개 이상의 스레드가 다른 CPU에서 같은 시간에 동시에 실행 (멀티코어)
스레드 주소공간과 컨텍스트
스레드 주소공간
스레드 주소 공간
-스레드가 생성되고 실행되는 동안 접근 가능한 메모리 영역
-
스레드 주소 공간은 프로세스의 주소 공간 내에 형성
-
스레드 주소 공간을 구성하는 요소들
-
스레드 사적 공간
-
스레드 코드
- 스레드 로컬 스토리지 (TLS, Threead local storage)
-
스레드 사이의 공유 공간 (프로세스 내에 있음)
- 프로세스의 코드
- 프로세스의 데이터 공간(로컬 스토리지 제외)
- 프로세스의 힙 영역
1) 스레드 코드 영역
- 스레드가 실행할 작업의 함수
- 스레드는 프로세스의 코드 영역에 있는 다른 모든 함수 호출 가능
2) 스레드 데이터 영역
- 스레드가 사용할 수 있는 데이터 공간
- 프로세스의 데이터 영역으로 사용
- 2개의 공간으로 구분
- 개별 스레드 전용 전역 변수 공간 (스레드 로컬 스토리지) - static __thread 와 같은 특별한 키워드로 선언, 컴파일러에 의해 결정
- 프로세스에 선언된 모든 전역 변수들은 모든 스레드에 의해 공유
- 스레드 사이의 통신 공간으로 유용하게 사용
3) 스레드 힙
- 모든 스레드가 동적 할당 받는 공간, 프로세스의 힙 공간 사용
- 스레드에서 malloc()를 호출하면 프로세스의 힙공간에서 할당받음
4) 스레드 스택
- 스레드가 생성될 때마다 프로세스의 사용자 스택의 일부분 할당
- 스레드가 시스템 호출로 커널에 진입할 때, 커널 내에 스레드를 위한 스택 생성 (커널 스택이라고 부름)
스레드 상태
- 스레드 일생
- 생성, 실행, 중단, 실행, 소멸의 여러 상태를 거치는 스레드 인생
- 스레드 상태는 TCB에 저장
- 스레드 상태
1) 준비 상태(Ready) - 스레드가 스케줄 되기를 기다리는 상태
2) 실행 상태(Running) - 스레드가 CPU에 의해 실행 중인 상태
3) 대기 상태(Blocked) - 스레드가 입출력을 요청하거나 sleep()과 같은 시스템 호출로 인해 커널에 의해 중단된 상태
4) 종료 상태(Terminated) - 스레드가 종료된 상태
스레드 운용
응용프로그램이 스레드에 대해 할 수 있는 운용의 종류
1) 스레드 생성
- 스레드는 스레드를 생성하는 시스템 호출이나 라이브러리 함수를 호출하여 다른 스레드 생성 가능
- 프로세스가 생성되면 자동으로 main 스레드 생성
2) 스레드 종료
- 프로세스 종료와 스레드 종료 구분 필요
- 프로세스 종료
프로세스에 속한 어떤 스레드라도 exit() 시스템 호출을 부르면 프로세스 종료( 모든 스레드 종료 )
메인 스레드의 종료(C프로그램에서 main() 함수 종료) - 모든 스레드도 함께 종료
모든 스레드가 종료하면 프로세스 종료 -> 스레드 종료
pthread_exit() 과 같이 스레드만 종료하는 함수 호출 시 해당 스레드만 종료
main() 함수에서 pthread_exit()을 부르면 역시 main 스레드만 종료
스레드 컨텍스트
1) 스레드 컨텍스트
- 스레드의 실행중인 상태 정보
- CPU 레지스터들의 값
- PC, SP, 데이터/상태 레지스터 등
- TCB에 저장됨
2) PC 레지스터
2) SP 레지스터
3) 상태 레지스터
4) CPU에는 수십 개의 레지스터
- 이들만 저장해두었다가 필요할 때 CPU에 복귀하면
- 이전에 실행하던 상태로 돌아갈 수 있음
스레드 제어블록
스레드 제어블록, TCB :스레드를 실행 단위로 다루기 위해 스레드에 관한 정보를 담은 구조체
- 스레드 엔터디, 스케줄링 엔터티 라고도 불림
- 커널 영역에 만들어지고, 커널에 의해 관리
- 스레드가 생성될 때 커널에 의해 만들어짐
- 스레드가 소멸되면 함께 사라짐
스레드와 TCB, 그리고 PCB의 관계
- 프로세스 : 스레드들이 생기고 활동하는 자원의 컨테이너
- TCB : 링크드 리스트로 연결
준비리스트와 블록리스트
1) 준비리스트
- 준비 상태의 스레드들의 TCB를 연결하여 관리하는 링크드 리스트
- 스레드 스케줄링은 준비 리스트의 TCB 중에서 하나 선택
2) 블록리스트
- 블록 상태의 스레드들의 TCB를 연결하여 관리하는 링크드 리스트
스레드 컨텍스트 스위칭
스레드 컨텍스트 스위칭
스레드 컨텍스트 스위칭
- 현재 실행중인 스레드를 중단시키고, 다른 스레드에게 CPU 할당
- 스레드 스위칭이라고도 부름
- 현재 CPU 컨텍스트를 TCB에 저장하고, 다른 TCB에 저장된 컨텍스트를 CPU에 적재
스레드 스위칭이 발생하는 4가지 경우
스레드 스위칭이 발생하는 4가지 경우
1. 스레드가 자발적으로 다른 스레드에게 양보
- yield() 등의 시스템 호출(혹은 라이브러리 호출) 을 통해
- 스레드가 시스템 호출을 실행하여 블록되는 경우
- read(), sleep(), wait() 등 I/O 가 발생하거나 대기할 수 밖에 없는 경우
- 스레드의 타임 슬라이스를 소진한 경우
- I/O 장치로부터 인터럽트가 발생한 경우
- 현재 실행 중인 스레드보다 더 높은 우선순위의 스레드가 I/O 작업을 끝낸 경우 등
** 상황에 따라 운영체제에 따라 이들 4가지 경우에도 스레드 스위칭이 일어날 수도 있고 아닐 수도 있음
스레드 스위칭이 발생하는 위치
- 스레드 스위칭이 이루어지는 위치는 2가지
1) 프로세스가 시스템 호출을 하여, 커널이 시스템 호출을 처리하는 과정에서
2) 인터럽트가 발생하여 인터럽트 서비스 루틴이 실행되는 도중 커널 코드에서
스레드 스위칭 과정
1) CPU 레지스터 저장 및 복귀
- 현재 실행 중인 스레드 A의 컨텍스트를 TCB-A에 저장
- TCB-B 에 저장된 스레드 B의 컨텍스트를 CPU에 적재
- CPU는 스레드가 B가 이전에 중단된 위치에서 실행 재개 가능
- SP 레지스터를 복귀함으로서 자신의 이전 스택을 되찾게 됨
** 스택에는 이전 중단될 때 실행하던 함수의 매개변수나 지역변수들이 그대로 저장되어 있음
2) 커널 정보 수정
- TCB-A와 TCB-B에 스레드 상태 정보와 CPU 사용 시간 등 수정
- TCB-A를 준비 리스트나 블록 리스트로 옮김
- TCB -B를 준비 리스트에서 분리
컨텍스트 스위칭 오버헤드
-
컨텍스트 스위칭에는 어떤 부담(오버헤드)이 있는가?
- 컨텍스트 스위칭은 모두 CPU작업 -> CPU 시간 소모
- 컨텍스트 스위칭의 시간이 길어나, 잦은 경우 컴퓨터 처리율 저하
-
구체적인 컨텍스트 스위칭 오버헤드
- 동일한 프로세스의 다른 스레드로 스위칭되는 경우
-
컨텍스트 저장 및 복귀
- 현재 CPU의 컨텍스트(PC, SP, 레지스터) TCB에 저장
- TCB로부터 스레드 컨텍스트를 CPU에 복귀
- TCB 리스트 조작
- 캐시 플러시와 채우기 시간
-
다른 프로세스의 스레드로 스위칭하는 경우
- 다른 프로세스로 교체되면, CPU가 실행하는 주소 공간이 바뀌는 큰 변화로 인한 추가적인 오버헤드 발생
- 추가적인 메모리 오버헤드
-
시스템 내에 현재 실행 중인 프로세스의 매핑 테이블을 새로운 프로세스의 매핑 테이블로 교체
- 추가적인 캐시 오버헤드
** 프로세스가 바뀌기 때문에, CPU 캐시에 담긴 코드와 데이터 무력화
새 프로세스의 스레드가 실행을 시작하면 CPU 캐시 미스 발생, 캐시가 채워지는데 상당한 시간 소요
커널 레벨 스레드와 사용자 레벨 스레드
커널 레벨 스레드와 사용자 레벨 스레드
- 스레드의 스케줄링 주체에 따라 2종류의 스레드로 구분
1) 커널 레벨 스레드 : 커널에 의해 스케줄링되는 스레드
2) 사용자 레벨 스레드 : 스레드 라이브러리에 의해 스케줄링되는 스레드
1) 커널레벨 스레드
- 응용프로그램이 시스템 호출을 통해 커널 레벨 스레드 생성
- 커널이 스레드에 대한 정보(TCB)를 커널 공간에 생성하고 소유
- 커널에 의해 스케줄
- 스레드 주소 공간(스레드 코드와 데이터) : 사용자 공간에 존재
- main 스레드는 커널 스레드
- 응용프로그램이 적재되어 프로세스가 생성될 때 자동으로 커널은 main 스레드 생성
2) 사용자레벨 스레드
- 응용프로그램이 라이브러리 함수를 호출하여 사용자 레벨 스레드 생성
- 스레드 라이브러리가 스레드 정보(U-TCB)를 사용자 공간에 생성하고 소유
- 스레드 라이브러리는 사용자 공간에 존재
- 커널은 사용자 레벨 스레드의 존재에 대해 알 수 없음
- 스레드 라이브러리에 의해 스케줄
- 스레드 주소 공간(스레드 코드와 데이터) : 사용자 공간에 존재
3) 순수 커널레벨 스레드
- 부팅 때부터 커널의 기능을 돕기 위해 만들어진 스레드
- 커널 코드를 실행하는 커널 스레드
- 스레드의 주소 공간은 모두 커널 공간에 형성
- 커널 모드에서 작동, 사용자 모드에서 실행되는 일은 없음
1) 2개의 순수 커널 레벨 스레드
- TCB1, TCB2
- 이들 스레드의 주소 공간은 커널에 있음.
2) 2개의 커널 레벨 스레드
- 프로세스 당 하나의 커널 레벨 스레드 (main 스레드) 자동 생성
- TCB3
- 커널은 단일 스레드 프로세스1을 적재할 때 자동으로 main 스레드 TCB3 생성
- 커널이 프로세스를 실행시키기 위함
-TCB4
- 커널은 멀티스레드 프로세스2를 적재할 때 자동으로 main 스레드 TCB4 생성
- 커널이 프로세스를 실행시키기 위함
- TCB3와 TCB4의 스레드 주소 공간은 모두 사용자 공간에 있음
3) 3개의 사용자 레벨 스레드
- 멀티스레드 프로세스2의 main() 함수가 라이브러리 함수를 호출하여 자신을 사용자 레벨 스레드로 등록
- U-TCB1 생성
- 멀티스레드 프로세스2의 main() 함수가 라이브러리 함수를 호출하여 2개의 사용자 레벨 스레드 추가 생성
- U-TCB2, U-TCB3 생성
4) 스레드 스케줄링
- 커널에 의한 스케줄
- 코어1 : TCB2 실행 (TCB2가 가리키는 커널 스레드 코드 2 실행)
- 코어2 : TCB4 실행 (TCB4가 가리키는 프로세스 내의 코드 실행)
** 처음에는 main() 함수에서 실행되지만, 어떤 함수인지 알 수 없음
커널은 프로세스 내에 하나의 스레드만 있다고 생각함
5) 멀티스레드 프로세스2에서의 사용자 스레드 스케줄링
-
스레드 라이브러리가 3개의 사용자 스레드 스케줄
-
예 : main() 함수가 스레드 라이브러리의 yield() 함수를 호출하면 이 함수는 현재 대기중인 U-TCB2, U-TCB3 중에서 하나를 선택한다. 만약 U-TCB3가 선택되었다면, U-TCB1에 현재 실행 주소 등을 저장해두고, U-TCB3에 저장된 실행 시작 주소(스레드 코드3)로 점프하여 실행 시작 -> U- TCB3이 스케줄 되었음
항목 | 사용자 레벨 스레드 | 커널 레벨 스레드 |
---|
정의 | 스레드 라이브러리에 의해 스케줄되는 스레드 | 커널에 의해 스케줄되는 스레드 |
구현 | 스레드 라이브러리에 의해 구현되고 다루어짐 | 커널에 의해 구현. 커널 API(시스템 호출) 필요 |
스레드 스위칭 | 사용자 모드에서 스레드 라이브러리에 의해 실행 | 커널 모드에서 커널에 의해 실행 |
컨텍스트 스위칭 속도 | 커널 레벨 스레드보다 100배 이상 빠르다고 알려짐 | 커널 내에서 상당 시간 지연 |
멀티스레드 응용프로그램 | 스레드 라이브러리를 이용하여 작성하기 쉽고, 스레드 생성 속도 빠름 | 시스템 호출을 이용하여 스레드 생성. 스레드 생성 속도 느림 |
이식성 | 운영체제 상관없이 작성 가능하므로 높은 이식성 스레드를 지원하지 않는 운영체제에서도 가능 | 스레드를 생성하고 다루는 시스템 호출이 운영체제마다 다르므로 이식성이 낮음 |
병렬성 | 멀티 CPU 컴퓨터나 멀티 코어 CPU에서 멀티스레드의 병령처리 안 됨 | 높은 병렬성. 커널 레벨 스레드들이 서로 다른 CPU나 서로 다른 코어에서 병렬 실행 가능 |
병렬성의 종류 | concurrency | parallelism |
블록킹 | 하나의 사용자 레벨 스레드가 시스템 호출 도중 입출력 등으로 인해 중단되면 프로세스의 모든 사용자 레벨 스레드가 중단됨 | 하나의 커널 레벨 스레드가 시시템 호출 도중 입출력 등으로 인해 중단되어도 해당 스레드만 중단 |
커널 부담 | 없음 | 커널 코드의 실행 시간 증가. 시스템 전체에 부담 |
스레드 동기화 | 스레드 라이브러리에 의해 수행 | 시스템 호출을 통해 커널에 의해 수행 |
관리의 효율성 | 커널 부담 없음 | 커널 부담 |
최근 경향 | 멀티 코어 CPU에 적합하지 않아 줄고 있는 추세 | 멀티 코어 CPU에서 높은 병렬성을 얻을 수 있어 많이 사용하는 추세 |
멀티스레드 구현
멀티스레드 구현
-
응용프로그램에서 작성한 스레드가 시스템에서 실행되도록 구현하는 방법
- 사용자가 만든 스레드가 시스템에서 스케줄 되고 실행되도록 구현하는 방법
- 스레드 라이브러리와 커널의 시스템 호출의 상호 협력 필요
-
3가지 방법
1) N:1 매핑(N개의 사용자 레벨 스레드를 1개의 커널 레벨 스레드로 매핑)
2) 1:1 매핑 (1개의 사용자 레벨 스레드를 1개의 커널 레벨 스레드로 매핑)
3) N:M 매핑 (N개의 사용자 레벨 스레드를 M개의 커널 레벨 스레드로 매핑)
N : 1 매핑
- 운영체제가 모든 프로세스를 단일 스레드 프로세스로 다룸
- 프로세스 당 1개의 커널 레벨 스레드(TCB) 생성
- 스케줄 가능한 엔터티라고 부름
- 프로세스의 모든 사용자 레벨 스레드가 1개의 커널 레벨 스레드에 매핑
- 사용자 레벨 스레드는 스레드 라이브러리에 의해 스위치 된다.
매핑의 뜻
- 사용자 레벨 스레드는 해당 커널 레벨 스레드가 스케줄되어야 실행 가능하도록 묶여 있음
- N:1 매핑의 장단점
1) 장점
- 단일 코어 CPU에서 멀티스레드 응용프로그램의 실행속도가 전반적으로 빠르다.
- 스레드 생성, 스케줄, 동기화 등이 커널로의 진입없이 사용자 공간에서 이루어지므로
2) 단점
- 멀티 코어 CPU가 보편화된 현대 컴퓨터에서 비효율적
- 사용자 레벨 스레드의 병렬처리 안됨
- 하나의 사용자 레벨 스레드가 블록되면 프로세스 전체 블록
- 다른 사용자 레벨 스레드도 실행되지 못함
1 : 1 매핑
-
사용자 레벨 스레드 당 1개의 커널 레벨 스레드(TCB) 생성
-
사용자 레벨 스레드는 매핑된 커널 레벨 스레드가 스케줄되면 실행
-
1:1 매핑의 장단점
1) 장점
-
개념이 단순하여 구현이 용이
-
멀티 코어 CPU에서 멀티스레드 응용프로그램에게 높은 병렬성제공
-
하나의 사용자 레벨 스레드가 블록되어도 응용프로그램 전체가 블록되지 않음
2) 단점
- 커널에게는 부담스러운 정책
- 사용자 레벨 스레드가 많아지면 모두 커널의 부담
N : M 매핑
2) 단점
- 구현하기 복잡하여 현대의 운영체제에서는 거의 사용되지 않음
이 글이 문제가 된다면 삭제하겠습니다.