2024. 4. 9. 23:35ㆍCS/Operating System
프로세스의 단점
프로세스도 좋지만 프로세스는 Heavy-weight이다. 프로세스 다음의 많은 요소를 포함해야 한다.
- address space
- OS resources
- Hardware execution state (PC, SP, registers 등등)
또, 프로세스를 생성하는 것은 data structure가 반드시 할당되어야 하 초기화되어야 하므로 비싸다.
프로세스 안에서 커뮤니케이션 하는 것 또한 항상 OS를 통해야 하므로 비싸다. 시스템 콜과 데이터를 복제하는 오버헤드가 들기 때문이다.
웹 서버 예제를 보자.
while(1){
int sock = accept(){
if((pid = fork()) == 0){
// Handle client request
} else{
// Close socket
}
}
이렇게 부모 프로세스에서 실행할게 굉장히 적다면 fork()를 써서 새로운 프로세스를 만들기엔 너무 과하다.
여러 작업을 처리하기 위해 fork로 복사본들을 생성하는 web server나 아무 동시 처리 멀티 프로세스를 생각해보자.
병렬로 실행되는 몇 개의 프로세스들을 만들어야 하고, 똑같은 address space를 만들어 줘야 한다. OS가 이런 일들을 해줘야 하는데, 이 과정들은 매우 비효율적이다. PCB, page tables 등등의 Space를 사용하고, OS structures를 생성하고, fork하고 address space를 copy하는 등의 시간도 많이 사용된다.
이런 프로세스들을 만드는 작업에서는 모든 멀티 프로세스는 같은 코드와 address를 사용한다. 또, 같은 권한과 파일, 소켓 등의 리소스도 사용한다. 그러나 공유하지는 않는다!
PC, 레지스터, SP, 스택 등 hardware execution state만 다른데 너무 많은 자원들을 따로 관리한다.
쓰레드의 도입
프로세스를 다시 생각해보자. 멀티 프로세스에서 프로세스들은 execution state만 다르고 나머지는 다 동일하다.
→ address space, 리소스 등의 일반적인 프로세스 속성은 남겨두고 PC, SP, register 등의 Execution state만 따로 빼서 실행하는 것이 쓰레드이다. 즉 쓰레드는 하드웨어의 수행 상태이다.
하나의 프로세스에 쓰레드를 여러개 둘 수 있다.
프로세스들은 process items는 공유하고 쓰레드는 PC, 레지스터, Stack, 스택 포인터, 상태(러닝인지, 레디인지 등)만 가지고 있으면 프로세스는 하나지만 세개의 프로세스가 돌 수 있게 만드는 것이다.
프로세스는 쓰레드를 담는 그릇이라 생각하면 된다. 쓰레드를 위해서는 쓰레드 관리 정보를 따로 가지고 있다. 마치 PCB처럼 운영체제는 TCB, Thread Control Block, TCB를 가진다.
메모리 공간 중 스택 공간을 쓰레드가 따로 쓸 수 있게 해줘야 한다.
하나의 프로세스에 쓰레드가 하나 돌고 있다면
이렇게되고 하나의 프로세스에 세 개의 쓰레드가 있다면
이렇게 된다. 코드, 데이터, 파일은 공통으로 사용하고, 레지스터와 스택은 쓰레드가 각자 가진다.
이게 멀티쓰레드 프로세스이다. 멀티 쓰레드는 프로세스의 컨텍스트와 동일한 과정으로 병렬로 실행된다. 멀티 쓰레드로 프로그래밍을 하려면 운영체제에 특수한 명령을 보내야 한다.
쓰레드란?
- 프로세스 내에 있는 인스트럭션의 시퀀스이다.
- 대부분 레지스터, PC, 스택 메모리 공간을 가진다.
- 스택 포인터와 스택은 구분해야 한다. 스택 포인터는 스택을 가리키고 있는 레지스터이다.
- 쓰레드는 대부분의 데이터와 프로세스 인스트럭션을 공유한다.
- 한 쓰레드가 공유된 데이터에 접근하면 다른 쓰레드도 볼 수 있다.
- 쓰레드는 대부분의 운영체제 상태를 공유한다.
웹 서버의 예시를 들면 이렇게 된다.
pdf 12장 참조.
기존에는 fork()를 했는데 create_thread(…) 이런식으로 쓰레드를 만들고 클라이언트의 요청을 처리하고 다시 돌아가는 식으로 동작하게 된다.
멀티쓰레딩의 장점
- 동시성을 만들기 굉장히 저렴하다.
- 시간적 측면, 메모리 측면에서 훨씬 빠르고 효율적이다.
- 프로그램의 구조가 개선된다.
- fork를 부르는 순간 굉장히 복잡해진다. 쓰레드는 훨씬 간단하다. 쓰레드는 만들기만 하면 되고, 멀티쓰레드로 동작하게 지정한 함수가 실행되므로 간단한 것이다.
- throughput도 좋아진다. I/O를 포함하고 있다면 특히나 좋아진다.
- throughput : 단위 시간당 처리할 수 있는 데이터나 작업의 양
- responsiveness도 좋아진다. 응답이 빨라진다는 뜻이다.
- 리소스를 공유하기에 굉장히 유용하다. 소켓, 열린 파일, 글로벌 변수값을 공유하는 것은 굉장히 유용할 수 있다.
- 멀티프로세서 아키텍처(하드웨어)의 응용이 좋아진다. 프로세스도 좋지만 프로세스는 Heavy-weight이다. 프로세스는 address space와 OS 리소스, Hardware execution station을 가지고 있어야 한다.
'CS > Operating System' 카테고리의 다른 글
[OS] User-level 쓰레드 VS 커널 쓰레드, Go Language (1) | 2024.04.12 |
---|---|
[OS] 프로세스와 쓰레드의 비교, pthreads, Signal handling (0) | 2024.04.11 |
[OS] Zombie & Orphan process와 PCB, Context Switch, fork (1) | 2024.04.03 |
[OS] 프로세스의 개념과 생성, fork 시스템 콜 (0) | 2024.04.02 |
[OS] I/O에서 데이터 전송 방식과 Timers, Protected Instruction (1) | 2024.04.01 |