Computer Science/Operating System

프로세스와 쓰레드

화요밍 2022. 5. 12. 10:58
728x90
반응형

1. 프로세스와 쓰레드의 정의

 

프로세스와 멀티쓰레딩의 구조

  • 프로세스 Process

프로세스는 실행 중인 프로그램을 말하며, 운영체제 입장에서의 작업 단위입니다.

디스크로부터 메모리에 적재되어 CPU의 할당을 받을 수 있는 것을 말합니다.

운영체제는 프로세스에 스택, 힙, 데이터 영역, 코드 영역을 할당합니다.

 

* 프로세스의 생성

 

프로그램이 프로세스가 되는 과정

  1. 프로그램이 CPU에 의해 실행된다.
  2. 프로세스가 생성되고 메모리에 프로세스 주소 공간(코드, 데이터, 스택 영역)이 할당된다.
  3. 이 프로세스의 메타데이터가 PCB에 저장된다.

 

* 프로그램과 프로세스

프로그램은 어떤 데이터를 사용하여 어떤 작업을 할지 그 절차를 적어놓은 것으로, 하드디스크 같은 저장장치에 저장되어 있는 정적의 상태입니다.

프로세스는 프로그램 실행을 위해 메모리에 적재한 동적인 상태로 운영체제로부터 PCB를 할당받습니다.

즉, 프로그램을 실행하면 프로세스가 됩니다.

 

* 코드, 데이터, 스택, 힙

  • 동적 영역
  1. 스택: 지역변수, 매개변수, 함수가 저장되는 영역, 컴파일 시 크기가 결정된다.
  2. 힙: 벡터와 같은 동적 배열이 할당되는 곳, 런타임 시 크기가 결정된다.
  • 정적 영역
  1. 코드 영역: 프로그램의 소스 코드가 들어가는 영역, 수정 불가능한 기계어(읽기 전용)로 저장되어 있다.
  2. 데이터 영역: 전역변수, 정적변수, 파일 등 각종 데이터를 모아놓은 영역으로 BSS와 Data 영역으로 나뉜다. 초기화 되지 않은 변수는 0으로 초기화되어 BSS 영역에 저장되며, 0이 아닌 다른 값으로 초기화된 변수는 Data 영역에 저장된다.

 

* 런타임과 컴파일타임

 컴파일타임은 작성한 소스코드를 실행 가능한 프로그램으로 만들기 위해 컴파일을 통해 기계어로 변환하는 과정을 말한다.

따라서 프로그램이 컴파일되는 과정에서 Syntax error나 Type check error, 파일참조 오류와 같은 문제가 발생하면 컴파일타임 에러를 발생시키고 에러가 발생한 소스코드 라인을 알려준다.

 런타임은 컴파일된 프로그램이 실행되어 동작하는 과정을 말한다.

프로그램이 실행되는 도중에 발생하는 오류를 런타임 에러라고 하고, Zero Division Error나 Null 참조 오류, 메모리 부족 오류 등이 있다.

 

 

 

  • 쓰레드 Thread

쓰레드는 프로세스의 실행 단위로, CPU 입장에서의 작업 단위입니다.

기본적으로 프로세스마다 최소 한 개의 쓰레드가 있으며, 여러 쓰레드로 구성할 수 있습니다.

CPU 스케줄러가 CPU에 전달하는 일 하나가 쓰레드이므로, CPU가 처리하는 작업의 단위는 프로세스로부터 전달받은 쓰레드입니다.

쓰레드는 한 프로세스 내에서 동작되는 여러 실행 흐름으로 프로세스 내 주소 공간이나 자원을 공유할 수 있습니다.

멀티쓰레딩인 경우, 같은 프로세스에 속한 다른 스레드들과 코드, 데이터 영역, 힙 그리고 열린 파일이나 신호와 같은 운영체제 자원들을 공유합니다.

각각의 쓰레드는 독립적인 작업을 수행해야하기 때문에 쓰레드 ID, 프로그램 카운터 PC, 레지스터 집합, 스택으로 구성됩니다.

 

* 스택과 PC를 쓰레드마다 독립적으로 할당하는 이유

 스택은 함수 호출 시에 전달되는 인자, 되돌아갈 주소값, 함수 내에서 선언하는 변수 등을 저장하기 위해 사용되는 메모리 공간입니다.

따라서 스택 메모리 공간이 독립적이면 함수 호출도 독립적으로 가능하다는 것이며, 이는 독립적인 실행 흐름이 추가 될 수 있다는 의미입니다.

따라서 프로세스 내 독립적인 실행 흐름인 쓰레드를 추가하기 위해서는 독립된 스택을 할당해야 합니다.

 

 프로그램 카운터는 실행해야 할 다음 명령어의 주소에 대한 포인터입니다.

쓰레드는 CPU를 할당받았다가 스케줄러에 의해 선점될 수 있습니다.

즉, 명령어가 연속적으로 수행되지 못할 수 있기 때문에 어디까지 명령어를 수행했는지를 기억하기 위해서 PC 레지스터를 독립적으로 할당합니다.


2. PCB(Process Control Block)

PCB는 운영체제에서 프로세스에 대한 메타데이터를 저장한 데이터를 말합니다.(Task Control Block, TCB라고도 합니다.)

프로세스가 생성되면 운영체제는 각 프로세스마다 고유한 PCB를 생성합니다.

프로세스가 생성될 때 스택, 힙, 데이터 영역, 코드 영역이 메모리에 할당되고, 이와 더불어 프로세스에 관한 메타데이터들이 PCB에 저장되어 관리됩니다.

PCB는 프로세스의 중요한 정보들을 가지고 있기 때문에 일반 사용자가 접근하지 못하도록 커널의 가장 앞부분에서 관리됩니다.

프로세스가 CPU를 할당받아 작업을 처리하다가 스케줄러에 의해 선점되면 진행 중인 작업을 저장하고 CPU를 반환합니다.

이때 작업 진행 상황을 PCB에 저장하고, 다시 CPU를 할당받으면 PCB에 저장되어 있던 작업 내용을 불러와 다시 작업을 수행합니다.

즉, Context Switching이 일어나 PCB를 교환합니다.

 

  • PCB의 구조PCB에 저장되는 프로세스 메타데이터

PCB

  1. Pointer: PCB를 연결해서 준비 상태나 대기 상태의 큐를 구현할 때 포인터 사용
  2. Process State: new, ready, running, waiting, terminated 등 프로세스의 상태를 저장
  3. Process ID(PID, Process number): 프로세스 구분자
  4. Program Counter(PC): 프로세스에서 실행해야 할 다음 명령어의 위치를 가리킴
  5. 프로세스 우선순위: 대기 상태의 큐는 프로세스의 우선순위에 따라 운영됨, 커널 프로세스의 우선순위가 사용자 프로세스보다 우선순위가 높음
  6. CPU register: 프로세스를 실행하기 위해 저장해야 할 레지스터의 중간값 저장(누산기 Accumulator, 색인 레지스터 index register, 스택 포인터 Stack pointer)
  7. 메모리 관리 정보: 프로세스의 메모리 위치 정보, 메모리 보호를 위해 사용하는 경계 레지스터 값과 한계 레지스터 값, 페이지 테이블, 세그멘테이션 테이블 등의 정보 저장
  8. 할당된 자원 정보: 프로세스를 실행하기 위해 사용하는 입출력 자원이나 오픈된 파일에 대한 정보 저장
  9. CPU 스케줄링 정보: CPU 스케줄러에 의해 중단된 시간, 프로세스의 우선순위, 스케줄 큐에 대한 포인터 등
  10. 계정 정보: CPU 할당 시간 및 사용 시간, 실행한 유저 정보 등
  11. PPID와 CPID: 부모 프로세스 ID와 자식 프로세스 ID

 

* PCB가 필요한 이유

 CPU에 할당된 프로세스의 작업 시간이 끝나거나 인터럽트에 의해 다른 프로세스로 전환이 일어날 때 다음으로 수행해야 하는 대기 중인 프로세스에 관한 정보를 PCB를 통해 알 수 있습니다.

 

* PCB는 어떻게 관리되는가?

Linked List 방식으로 관리된다.

새롭게 생성된 PCB가 List의 Head가 됩니다.

주소값으로 연결되어 있는 링크드 리스트이기 때문에 프로세스가 생성되면 삽입되고, 프로세스가 완료되면 삭제됩니다.

 

* PCB에서 Pointer의 역할

대기 상태의 프로세스는 하나의 큐에 모여있는 것이 아니라, 입출력 종류에 따라 다른 큐에 쌓이게 된다.

따라서 입출력이 완료되면 해당 입출력을 대기하는 큐에서 PCB를 찾아 준비 상태로 옮겨줘야 하고, 해당 PCB를 찾기 위해 포인터를 사용한다.


3. TCB(Thread Control Block)

 

쓰레드 별로 존재하는 자료구조로 PC, Register Set(CPU 정보), PCB를 가리키는 포인터를 가집니다.

쓰레드에 관한 정보만 담기 때문에 PCB보다 더 적은 데이터를 가집니다.

Ready queue, Wait queue는 TCB를 가리키는 포인터를 가지고 있습니다.

따라서 쓰레드에 관한 Context Switching이 일어날 때 TCB 정보를 저장하고 로드합니다.

 


4. Context Switching

  • 프로세스에서 일어나는 Context Switching

 

Process Context Switching

CPU가 이전 프로세스의 상태를 PCB에 저장하고, 다음 수행해야 하는 프로세스의 정보를 PCB로부터 로드하여 레지스터에 적재하는 과정을 말합니다.

인터럽트가 발생하거나, CPU 사용 시간이 끝났거나(Time Out), I/O 작업을 대기해야 하는 경우 발생하는 System Call에 Context Switching이 발생합니다.

즉, 프로세스가 Ready 상태에서 Running 상태로, Running 상태에서 Waiting 또는 Ready 상태로 바뀔 때 발생합니다.

 

* Context Switching의 OverHead

 멀티 프로세싱의 경우, 문맥교환으로 인한 OverHead를 감수해야 한다.

프로세스를 수행하다가 I/O 이벤트가 발생해서 프로세스를 Waiting 상태로 전환시키는 경우, I/O 작업이 끝날 때까지 CPU가 쉬게 하는 것보다 다른 프로세스를 수행하는 것이 더 효율적이기 때문에 Context Switching을 한다.

이로 인해 CPU가 쉬지 않고 여러 작업을 병렬적으로 수행함으로써 사용자에게 빠른 일처리를 제공할 수 있기 때문입니다.

 

Context Switching이 일어날 때 발생하는 오버헤드 중 하나가 Cache miss입니다.

캐시에는 현재 실행 중인 프로세스가 가지고 있는 메모리 주소가 있습니다.

문맥교환이 일어나면 기존 프로세스의 정보들이 필요가 없어지니 Cache clear를 진행합니다.

따라서 문맥교환이 일어난 초기에 캐시 미스가 자주 발생하기 때문에 메모리 참조가 발생함에 따라 오버헤드가 됩니다.

 

하지만 같은 프로세스 내 다른 쓰레드 간의 Context Switching의 경우, 데이터를 공유하기 때문에 캐시를 비우지 않기 때문에 캐시 미스로 인한 오버헤드는 줄어듭니다.

 

 

  • 쓰레드에서 일어나는 Context Switching

TCB in Ready queue

1. 같은 프로세스 내에 있는 쓰레드 간 문맥교환

쓰레드는 스택 영역을 제외한 모든 메모리를 공유하기 때문에 프로세스의 문맥교환보다 비용이 더 적고 시간도 적게 걸립니다.

따라서 TCB 정보만 저장하고 로드하면 되므로 오버헤드가 작습니다.(cache miss overhead도 작습니다.)

 

2. 다른 프로세스에 있는 쓰레드 간 문맥교환

TCB와 PCB 정보를 모두 저장하고 로드하는 과정이 필요합니다.

 

 


5.  프로세스의 상태

  • 활성 상태

프로세스의 상태

1. 생성 상태, New

프로그램이 메모리를 할당받고, 운영체제로부터 PCB가 생성됩니다. 이때 프로세스가 실행 준비가 완료됩니다.

 

2. 준비 상태, Ready

살행 대기 중인 프로세스가 순서를 기다리는 상태입니다.

PCB가 Ready Queue에 쌓여 CPU 스케줄러에 의해 관리됩니다.

CPU 스케줄러가 Ready Queue를 몇 개로 운영할지, 큐에 있는 어떤 프로세스의 PCB를 실행 상태로 보낼지를 결정합니다.

 

* Dispatch

CPU 스케줄러가 실행할 PCB를 선택하는 작업을 Dispatch 명령으로 처리합니다.

Dispatch(PID)를 실행하면 해당 PID의 프로세스가 준비 상태에서 실행 상태로 바뀌게 됩니다.

 

3. 실행 상태, Running

프로세스가 CPU를 할당받아 실행되는 상태입니다.

CPU의 개수로 실행 상태로 들어가는 프로세스의 개수가 정해집니다.

실행 상태의 프로세스는 타임 슬라이스 동안 작업이 진행되며, 시간을 다 사용하면 timeout(PID)가 실행됩니다.

  • timeout(PID)가 호출되면 PCB를 실행 상태에서 준비 상태로 옮깁니다.
  • 타임 슬라이스 내에 프로세스의 작업이 완료되면 exit(PID)가 실행되어 프로세스가 정상 종료됩니다.
  • 프로세스가 입출력을 요청하면 CPU는 입출력 관리자에게 입출력을 요청하고 block(PID)를 실행하며, 해당 프로세스는 대기 상태로 바뀝니다.

 

4. 대기 상태, Waiting

실행 상태에 있는 프로세스가 입출력을 요청하면 입출력이 완료될 때까지 기다리는 상태입니다.

대기 상태의 프로세스들은 입출력 장치별로 마련된 큐에서 대기합니다.

입출력이 완료되면 인터럽트가 발생하여 wakeup(PID)를 통해 해당 인터럽트로 깨어날 프로세스를 찾아 PCB가 준비 상태로 이동하게 됩니다.

 

5. 완료 상태, Terminate

프로세스가 종료되는 상태입니다.

정상 종료된 프로세스는 프로세스에 할당된 메모리와 PCB를 폐기합니다.

비정상적으로 종료된 프로세스인 경우(abort), 디버깅을 위해 강제 종료 직전의 메모리 상태를 저장장치로 옮기는 Core dump가 발생합니다.

 

 

  • 보류 상태

보류 상태를 포함한 프로세스의 상태

보류 상태는 프로세스가 메모리에서 잠시 쫓겨난 상태입니다.

컴퓨터의 성능을 떨어뜨리거나 실행을 미뤄도 큰 지장이 없는 프로세스의 경우 보류 상태로 넘어갑니다.

보류 상태의 프로세스는 메모리에서 쫓겨난 데이터가 임시로 보관되는 곳인 스왑 영역에 보관됩니다.

 

  • 프로세스가 보류 상태가 되는 경우
  1. 메모리가 부족해 일부 프로세스를 메모리 밖으로 내보낼 때
  2. 프로그램에 오류가 있어 실행을 미뤄야 할 때
  3. 바이러스와 같이 악의적인 공격을 하는 프로세스라고 판단될 때
  4. 너무 긴 주기로 반복되는 프로세스라 메모리 밖으로 내보내도 괜찮을 때
  5. 입출력을 기다리는 프로세스(대기 상태의 프로세스)의 입출력이 계속 지연될 때

 

  • 보류 대기 상태, Suspend wait

대기 상태에서 옮겨진 상태입니다.

해당 프로세스가 재시작하면 원래의 활성 상태인 대기 상태로 돌아갑니다.

 

  • 보류 준비 상태, Suspend ready

준비 상태에서 옮겨지거나, 보류 대기 상태에서 해당 프로세스가 요청한 입출력이 완료되어 입출력이 완료되면 보류 준비 상태로 옮겨집니다.

해당 프로세스가 재시작하면 원래의 활성 상태인 준비 상태로 돌아갑니다.

 

 

* 휴식 상태 Pause와 보류 상태

휴식 상태는 프로세스가 작업을 일시적으로 쉬고 있는 상태로 프로세스가 메모리에 있으나 멈춘 상태입니다.

보류 상태는 프로세스가 메모리에서 잠시 쫓겨난 상태라는 점에서 휴식 상태와 다릅니다.

 


6. 멀티태스킹, 멀티쓰레드, CPU 멀티스레드, 멀티프로세싱

 

 

  • 멀티태스킹

운영체제가 CPU에 작업을 줄 때 시간을 잘게 나누어 배분하는 것을 말합니다.

여러 쓰레드에 시간을 잘게 나누어주는 시스템을 시분할 시스템이라고 합니다.

 

  • 멀티쓰레드

프로세스 내 작업을 여러 개의 쓰레드로 분할함으로써 작업의 부담을 줄이는 프로세스 운영 기법입니다.

멀티쓰레드는 운영체제가 프로세스를 여러 쓰레드로 분할하는 소프트웨어적인 방법이라는 점에서 CPU 멀티쓰레드와 다릅니다.

 

  • CPU 멀티쓰레드

파이프라인 기법을 이용해서 동시에 여러 쓰레드를 처리하도록 만드는 병렬 처리 기법입니다.

하드웨어적인 방법으로 하나의 CPU에서 여러 쓰레드를 동시에 처리하는 방법입니다.

 

  • 멀티프로세싱

CPU를 여러 개 사용해서 여러 개의 스레드를 동시에 처리하는 작업 환경입니다.

하나의 컴퓨터에 여러 개의 CPU가 있거나, CPU 내 여러 개의 코어에 쓰레드를 배정해서 동시에 작업하는 것입니다.

네트워크로 연결된 여러 컴퓨터에서 쓰레드를 나누어 협업하는 분산 시스템도 속합니다.

 


7. 프로세스의 복사와 전환

  • fork()

 

fork() 시스템 호출을 통해 실행 중인 프로세스로부터 새로운 프로세스를 복사할 수 있습니다.

프로세스를 복사하면 기존 프로세스는 부모 프로세스가 되고, 새로 생성된 프로세스는 자식 프로세스가 됩니다.

PID, 프로세스가 위치한 메모리 위치, PPID와 CPID 정보만 변경되고 나머지는 부모 프로세스와 같습니다.

 

* fork() 시스템 호출의 장점

  1. 하드디스크로부터 프로그램을 가져오는 과정 없이 기존 메모리에서 복사하기 때문에 프로세스 생성 속도가 빠릅니다.
  2. 부모 프로세스가 사용하던 모든 자원이 자식 프로세스에 상속됩니다.
  3. 자식 프로세스를 종료하면 자원을 부모 프로세스가 정리하기 때문에 시스템 관리를 효율적으로 할 수 있습니다.

 

 

  • exec()

기존의 프로세스를 새로운 프로세스로 전환하는 시스템 호출입니다.

코드 영역에 있는 기존의 내용을 지우고 새로운 코드로 바뀌며, 데이터 영역이 새로운 변수로 채워지고 스택 영역이 리셋됩니다.

이미 만들어진 PCB, 메모리 영역, 부모-자식 프로세스 관계를 그대로 사용할 수 있다는 장점이 있습니다.


8. 멀티태스킹과 멀티스레드

 

  • 멀티태스킹

fork() 시스템 호출로 프로세스를 여러 개 만드는 멀티태스킹의 경우, 스택과 힙과 같은 동적 영역 뿐만아니라 프로세스가 실행되는 동안 바뀌지 않는 영역인 정적 영역까지 복사되기 때문에 메모리 낭비가 되는 단점이 있습니다.

 

하지만 각 프로세스가 독립적이기 때문에 한 프로세스에 문제가 생기더라도 다른 프로세스에는 영향을 미치지 않는다는 장점이 있습니다.

최근에는 메모리가 넉넉하고 멀티코어 CPU가 대중화되어 있기 때문에 멀티태스킹이 효율적일 수 있습니다.

 

예를 들어 크롬 브라우저의 경우, 각 창이 독립적인 프로세스이므로 한 창이 문제가 생겨서 종료되더라도 다른 화면에 미치는 영향이 작습니다.

 

  • 멀티쓰레드

 하나의 프로세스 내에 여러 개의 쓰레드를 생성하는 멀티쓰레드의 경우에는 정적 영역에 있는 자원들을 공유함으로써 자원의 낭비를 막으므로 이러한 측면에서 멀티태스킹보다 더 효율적입니다.

또한, 특정 쓰레드가 입출력이 끝날 때까지 대기 상태에 머물러도 다른 쓰레드는 독립적으로 작업을 수행하므로 단일쓰레드인 프로세스와 비교할 때에도 작업의 효율이 좋습니다.

 

 하지만 멀티쓰레드의 경우, 한 쓰레드에 문제가 생기면 모든 쓰레드가 자원을 공유하기 때문에 전체 프로세스에 영향을 미칩니다.

즉, 다른 쓰레드에도 영향을 미치게 됩니다.

 

예를 들어 인터넷 익스플로어의 경우, 한 창이 강제로 종료되면 인터넷 익스플로어 전체가 종료됩니다.

 


9. 멀티스레드 모델

 


출처

  • 참고 도서
  1. 면접을 위한 CS 전공지식 노트 - 주홍철 지음
  2. 쉽게 배우는 운영체제 - 조성호 지음

 

 

GitHub - JaeYeopHan/Interview_Question_for_Beginner: Technical-Interview guidelines written for those who started studying progr

:boy: :girl: Technical-Interview guidelines written for those who started studying programming. I wish you all the best. :space_invader: - GitHub - JaeYeopHan/Interview_Question_for_Beginner: Techn...

github.com

 

GitHub - gyoogle/tech-interview-for-developer: 👶🏻 신입 개발자 전공 지식 & 기술 면접 백과사전 📖

👶🏻 신입 개발자 전공 지식 & 기술 면접 백과사전 📖. Contribute to gyoogle/tech-interview-for-developer development by creating an account on GitHub.

github.com

 

쓰레드(Thread)란 무엇인가?

Index

goodgid.github.io

 

728x90
반응형