이 글은 개인의 학습을 목적으로 정리한 글입니다. 이점 참고하고 읽어주세요;)
사용자 프로그램에서 입출력 자료가 필요할 때: 시스템 콜을 통해 운영체제에게 입출력 작업 요청. 운영체제에서 입출력 디바이스에 명령을 내려서 작업 실행. 입출력 작업은 좀 긴 시간에 걸쳐 실행.
- 이 과정에서 입출력 작업이 끝날 때까지 다른 일을 하지 않고, 입출력 작업이 끝나야 다시 작업을 시작하면 그건 동기식(Synchronous) 작업
- 이 과정에서 입출력 작업이 끝날 때 까지 기다리지 않고, 그 입출력 작업이 끝나든 끝나지 않든 CPU를 다른 프로세스에 사용하면 이게 비동기식(Asynchronous) 작업
동기식 입출력(Synchronous I/O)
구현 방법1. I/O가 끝날 때까지 CPU를 그 작업에 잡고 있음
구현 방법2. 어차피 다른 작업은 못하니, CPU를 다른 ready 상태의 프로세스에 넘겨주는 것
프로세스 내부에 CPU 수행 단위가 여러 개 있는 경우에 이를 쓰레드라고 부름
프로세스가 하나 주어지면 위와 같이 코드, 데이터, 스택 영역의 주소공간이 생성됨. 그리고 이 프로세스를 관리하기 위해 운영체제 내부에 PCB를 두고 프로세스의 상태와, 프로세스 ID, 메모리의 어느 부분을 실행하는지 가리키는 PC, 레지스터 셋 등등을 관리. PCB는 현재 메모리의 어느 부분(코드의 어느 부분)을 실행하는지 PC가 가리킴.
동일 프로세스를 여러 개 실행시켜야 하면 그 수 만큼의 주소 공간을 만들어야 함. 이는 메모리의 낭비.
이렇게 같은 일을 하는 프로세스를 여러 개 띄워놓고 싶다면, 주소공간을 하나만 띄워놓고 현재 각 프로세스마다 다른 부분의 코드를 실행할 수 있게 해 주면 됨. 이게 쓰레드의 개념.
쓰레드는 프로세스는 하나만 띄워놓고, 현재 CPU가 코드의 어느 부분을 실행하고 있는가를 가리키는 프로그램 카운터만 여러 개를 두는 것. 프로세스 하나에 CPU 수행 단위만 여러 개 할당. CPU의 실행 단위
프로그램을 실행시키려면 CPU가 인스트럭션의 어느 부분을 처리하고 있는지 가리키는 프로그램 카운터가 있어야 하고, 현재 레지스터에 어떤 값을 넣고 프로그램 카운터가 코드의 어느 부분을 가리키고 있는지 각 쓰레드(CPU의 수행 단위)마다 별도로 유지 및 관리
쓰레드는 하나의 프로세스 내에서 공유할 수 있는 건 최대한 공유.
1) 주소 공간
2) 프로세스의 상태
3) 프로세스의 각종 자원들
하지만 CPU 수행과 관련된 정보들은 별도로 관리
1) 프로그램 카운터
2) 레지스터
3) 스택 등
Thread: CPU의 수행 단위
프로그램 카운터, 레지스터 셋, 스택 공간만 독자적으로 관리
프로세스 내부에서 코드 영역, 데이터 영역, OS 자원은 쓰레드 간에 공유(= task)
1. 쓰레드 하나가 blocked 상태일 때, 다른 thread가 CPU를 잡고 작업 가능
ex. 웹 브라우저를 통해 웹 페이지를 읽는 작업
1) 네트워크를 통해 웹 페이지를 불러와야 함. 이것 역시 I/O 작업
2) I/O 작업은 오래 걸리기 때문에 웹 브라우저는 blocked 상태. 사용자는 답답함ㅠ
3) 웹 브라우저를 여러 개의 쓰레드로 구성하면, 하나의 쓰레드가 웹 페이지에서 그림 등을 불러오는 동안 이 프로세스를 blocked 처리하지 않고 다른 쓰레드가 불러온 text를 먼저 웹 브라우저에 로딩. 사용자는 좀 덜 답답
2. 같은 일을 하는 작업에 대해 별도의 프로세스를 만들어 메모리 등의 자원을 낭비하지 않고(프로세스별로 독자적인 주소 공간을 차지하기 때문에 메모리의 낭비) 자원을 절약.
3. CPU가 여러 개 있으면 병렬성을 높일 수 있음
쓰레드는 CPU 수행과 관련된 정보를 별도로 관리함.
1) 빠른 응답성. 웹 브라우저의 예시. 사진을 가져오는 동안 미리 가져온 텍스트를 창에 씌움
1. HTML
2. HTML에 있는 이미지를 불러오기 위해 다시 웹 서버에 요청
3. 그럼 이 작업이 오래 걸리기 때문에 이 프로세스를 block(동기식Synchronous)
4. 이걸 이렇게 하지 않고 브라우저를 여러 개의 쓰레드를 이용하면 일단 HTML을 가져오고
5. 웹 서버에 요청한 네트워크 쓰레드만 block이 됨. 그럼 이때 다른 쓰레드가 이미 가져온 HTML의 텍스트만이라도 화면에 보여줌(비동기식Asynchronous)
2) 자원의 공유: 동일 작업에 대해 여러 개의 프로세스를 만들지 않고, 하나의 프로세스 내에 여러 개의 쓰레드를 줌. 자원을 효율적으로 사용 가능
3) 경제성..?: 더 빠른 속도. 응답성과는 좀 다름.
프로세스 하나를 만드는 건 꽤 오버헤드가 큼. 그런데 이미 만들어진 프로세스 위에 쓰레드를 만드는 작업은 프로세스를 만드는 작업에 비하면 오버헤드가 그다지 심하지 않음. Context switch 역시 프로세스에서 다른 프로세스로 CPU가 넘어가는 작업은 오버헤드가 큼. CPU관련 정보를 저장하고, 캐시 메모리 플러시(캐시 메모리를 비움) 등. 하지만 프로세스 내에서 쓰레드를 스위치하는 건 이에 비하면 비교적 간단.
4. (CPU가 여러 개 있는 환경에서만) 각각의 쓰레드가 다른 CPU에서 병렬적으로 처리 가능. 더 빠른 결과 출력.
Kernal Threads: 쓰레드가 여러 개 있는 사실을 운영체제 커널이 알고 있음. 하나의 쓰레드에서 다른 쓰레드로 넘어가는 것도 커널이 프로세스 스케쥴링처럼 관리
User Threads: 프로세스 내부에 쓰레드가 여러 개 있다는 걸 운영체제는 모름. 유저 프로그램이 스스로 여러 개의 쓰레드를 관리함. 라이브러리의 지원을 받아서. 때문에 약간의 구현상 제약점은 존재.
'Information Technology > OS' 카테고리의 다른 글
[운영체제] Process Management(2) (0) | 2020.01.26 |
---|---|
[운영체제] Process Management(1) (0) | 2020.01.26 |
[운영체제] Process(1) (0) | 2020.01.20 |
[운영체제] System Structure & Program Execution(2) (0) | 2020.01.15 |
[운영체제] System Structure & Program Execution(1) (0) | 2020.01.13 |