[인프런 워밍업 클럽 3기 - CS] - 1주차 발자국 (운영체제) - 2

[인프런 워밍업 클럽 3기 - CS] - 1주차 발자국 (운영체제) - 2

💻 프로세스와 쓰레드

📌 프로그램과 프로세스

프로그램: 저장장치에 저장된 명령문의 집합체 (Application, .exe,,,)

프로세스: 실행 중인 프로그램. "실행 중"은 하드디스크에 저장된 프로그램이 메모리에 올라갔을 때를 의미한다.

프로그램은 저장장치에 저장만 되는 수동적인 존재이지만,

프로세스는 메모리, CPU 스케줄링 알고리즘, 입/출력도 사용하는 능동적인 존재.

 

프로세스의 구조

1. 코드 영역

- 자신을 실행한는 코드가 저장

2. 데이터 영역

- 스태틱 변수와 전역 변수 저장

3. 스택 영역

- 지역 변수와 함수 호출을 위한 정보 저장

4. 힙 영역

- 프로그래머가 동적으로 메모리를 할당

- free(), malloc()을 통해 메모리 관리

 

컴파일 과정

1. 전처리기를 통해 매크로로 정의한 숫자를 치환하고 필요한 파일을 불러온다.

2. 파일의 확장자(.i)

3. 컴파일 (C언어 > 어셈블리어)

4. 파일의 확장자(.s)

5. 어셈블리어 > 기계어

6. 파일의 확장자(.o)

7. 링킹을 통해 파일의 확장자(.exe)로 변경

 

프로세스 실행 과정

1. 두 숫자를 더하는 코드를 작성

2. 컴파일

3. .exe 파일을 실행

4. 메모리에 파일이 올라감 (프로세스)

5. CPU 내 제어장치가 파일을 읽어가며 레지스터 저장 및 연산

6. 결과 메모리 저장

 

📌 멀티프로그래밍과 멀티프로세싱

유니 프로그래밍

(메모리 관점) 메모리에 오직 하나의 프로세스가 올라온 것 (I/O 작업이 일어나면 대기)

멀티 프로그래밍

(메모리 관점) 메모리에 여러 개의 프로세스가 올라온 것 (I/O 작업 대기 시, 다른 프로세스 실행)

멀티 테스킹

메모리에 올라온 여러 프로세스들을 번갈아가며 짧게 실행시키며 동시에 실행시키는 체감

멀티 프로세싱

(CPU 관점) CPU가 여러 개 있는 것을 멀티 프로세서 라고 하며, 멀티 프로세서로 작업하는 것을 멀티 프로세싱 이라고 한다.

 

과거

-> 유니 프로그래밍 + 스와핑 방식

1. 메모리에 하나의 프로세스를 올려 처리 한 후, 저장장치에 저장

2. 다른 저장장치의 프로세스를 메모리에 올려 CPU 처리

3. 스와핑이란 하나의 프로세스가 마무리되면 저장장치로 내리고 새로운 프로세스 메모리에 올리는 기법

 

현재

-> 멀티 프로그래밍 + 멀티 프로세싱 방식

1. 메모리에 여러 프로세스가 올라오고

2. 시분할 처리를 통해 각각의 프로세스 짧은 시간동안 교대로 처리

 

📌 PCB

운영체제는 여러 개의 프로세스를 전부 관리하고 공평하게 실행해야 한다.

프로세스 관리는 PCB(Proccess Control Block) 를 생성하여 연결리스트의 자료구조로 관리한다. 프로세스 종료 시에는 연결리스트에서 해당 PCB를 제거한다.

 

PCB 구조

1. 포인터: 부모, 자식 프로세스에 대한 포인터를 저장

- 프로세스 계층 구조 파악 및 프로세스 종료 시, 프로세스 상태 추적 가능

2. 프로세스 상태: 현재 어떤 상태에 있는지 나타내는 정보 (생성, 준비, 실행, 대기, 완료)

3. 프로세스 ID: 프로세스 식별자 저장

- 프로세스는 고유한 PID를 가짐

- 프로세스 구분하는데 사용되며 시스템 내에 유일해야 함

4. 프로그램 카운터: 다음에 실행될 명령어의 주소를 저장

- 현재 실행 중인 명령어의 다음 주소를 저장

- Context Switch가 발생하면, 해당 프로세스가 진행해야 할 명령어의 주소로 복구

5. 레지스터 정보: 프로세스가 실행될 때 사용된 레저스터 정보

- 프로세스 중단, 전환 시, PCB에 레지스터 값 저장한 후, 다시 실행될 때 복구

6. 메모리 관련 정보: 프로세스가 메모리에 저장된 위치 정보

- 프로세스가 사용하는 메모리 영역(코드, 데이터, 스택, 힙,,)과 주소를 관리

- 가상 메모리 시스템에서 중요 - 프로세스 간 메모리 영역 분리

7. CPU 스케줄링 정보: 우선순위, 최종 실행시간, 점유 시간 등 CPU를 얼마나 효율적으로 사용할 지에 대한 정보

8. I/O 상태 정보 : 프로세스가 현재 어떤 입출력 작업을 수행 중인지에 대한 정보

9. 열린 파일 목록(Open File List) : 현재 열고 있는 파일들의 목록 관리

 

📌 프로세스 상태

1. 생성 (New): 메모리에 프로그램 적재 요청

- PCB 생성

2. 준비 (Ready): CPU 자원 할당을 위해 기다리는 상태

3. 대기 (Waiting): 입출력 요청 시, 입출력이 완료될 때까지 대기하는 상태

- 입출력 완료까지 CPU 대기는 비효율적

- 입출력을 기다리는 것은 대기 상태로 두고 CPU는 다른 작업 (시스템 자원 낭비 최소화)

- 입출력이 완료되면 준비 상태로 전환

4. 실행 (Running): 스케쥴러에 의해 CPU를 할당받아, 부여된 시간만큼 실행되는 상태

- CPU 개수만큼 실행 프로세스가 생성

- 부여된 시간을 초과하면 CPU를 강제로 빼앗으며 준비 상태로 전환.

- 실행 도중, 입출력 요청을 하면 다시 준비 상태로 전환

5. 완료 (Terminated): 프로세스 종료

- 메모리에서 데이터 제거 및 PCB 제거

 

📌 컨텍스트 스위칭

프로세스를 실행 중인 상태에서 다른 프로세스를 실행하기 위해 실행중인 프로세스 상태를 저장하고 교체

운영체제에 의해 실행 중인 프로세스의 내용이 PCB에 수정되고, 다음 프로세스의 PCB 내용대로 CPU가 세팅 됨.

 

과정

1. 프로세스 A의 CPU 점유 시간 초과

2. 인터럽트 발생

3. CPU의 레지스터 값 등을 PCB A에 저장

4. PCB B를 참조해서 이전 프로세스 B의 작업을 이어감

- 프로그램 카운터(다음에 실행될 명령어 주소)를 통해 이어서 명령어 실행 가능

5. 프로세스 B의 CPU 점유 시간 초과

6. 인터럽트 발생

7. CPU의 레지스터 값 등을 PCB B에 저장

 

📌 프로세스 생성과 종료

프로세스 생성

1. .exe 실행

2. 코드 영역, 데이터 영역를 메모리에 올려 스택과 힙 구조의 공간을 확보.

3. PCB를 만들어서 값을 초기화

컴퓨터 부팅 시에 0번 프로세스가 한번만 생성되며, 나머지 실행되는 모든 프로세스는 fork()로 복사하여 자식프로세스를 생성한다.

exec()함수를 통해 자식 프로세스의 코드를 복사된 부모 프로세스의 코드에 덮어쓸 수 있다.

 

#include <stdio.h>
#include <unistd.h>

int main() {
   int pid;
   pid = fork();
   // 부모 프로세스는 pid = 1;
   // 자식 프로세스는 pid > 1;
   // 실패 시 -1 리턴

   if(pid == 0){ // 자식
      execlp("InternetBrowser", "0", NULL);
      exit(0);
   } else { // 부모
      wait(NULL);
      printf("인터넷 브라우저 닫힘");
      exit(0);
   }
}

1. 해당 프로세스를 fork()를 통해 부모와 자식 프로세스는 동일한 코드를 갖고 있는다. (pid는 서로 다름)

2. CPU 스케쥴링에 따라 프로세스가 실행된다.

3. 만약 부모 프로세스가 먼저 실행되면, 조건문에 의해 else절이 실행

4. wait() 함수는 exit() 신호가 오기 전까지 하위 코드를 실행하지 않음

5. 스케쥴링에 의해 자식 프로세스로 스위칭

6. if절이 실행되어 execlp()를 통해 InternetBrowser 프로세스가 실행

7. 인터넷 브라우저 실행에 실패할 경우, exit() 함수가 실행 (성공 시, InternetBrowser 프로세스 실행)

8. 스케쥴링에 의해 부모 프로세스로 스위칭

9. 자식 프로세스의 exit() 신호로 wait() 함수를 통과하여 하위 코드가 실행

exit(): 자식 프로세스가 부모 프로세스에게 정상 종료를 알리는 함수

부모 프로세스는 자식 프로세스의 exit status를 읽고 자식 프로세스를 정리

부모 프로세스가 자식 프로세스보다 먼저 종료되거나, 자식 프로세스의 비정상 종료 시 좀비 프로세스라고 부른다.

 

📌 쓰레드

프로세스가 생성될 때마다 PCB와 메모리(코드, 데이터, 스택, 힙 등)영역을 만들어줘야 한다.

웹브라우저의 탭이 추가될 때마다 프로세스의 복사가 계속해서 이루어진다면 시스템 자원의 낭비가 점차 늘어난다.

=> 하나의 프로세스 안에 1개 이상의 쓰레드를 생성.

운영체제는 프로세스 내 쓰레드 단위로 관리

 

비교

1. 안정성: 프로세스는 독립적이기 때문에 다른 프로세스의 영향을 받지 않지만 쓰레드는 자원을 공유하기에 프로세스에 문제가 생기면 모든 프로세스에 영향을 끼친다.

2. 속도와 자원: 각 프로세스는 IPC를 통해 다른 프로세스와 통신을 해야하니 오버헤드가 크다. 쓰레드간에 통신은 자원이 공유되니 오버헤드가 적다.

 

📌 더 찾아본 점

프로그래밍 개념 구분?

image

멀티 프로그래밍과 멀티 태스킹의 차이?

멀티 프로그래밍은 메모리 관점에서 여러 프로그램을 메모리에 올려두고 CPU가 필요할 때마다 실행

멀티 테스킹은 CPU 관점에서 여러 작업을 빠르게 전환(시분할)하며 동시에 작업하는 것처럼 보임

 

`exec()`함수는 무엇인가?

자식 프로세스가 새로운 프로그램을 실행할 때, 자식 프로세스의 코드, 데이터, 힙, 스택 등을 새로운 프로그램으로 덮어쓰는 함수.

- 자식 프로세스의 메모리 공간을 새로운 프로그램으로 대체하며 exec() 이후에는 자식 프로세스 코드가 실행되지 않음.

- execl(), execp(), execv(), execvp(), execlp() 등이 exec()함수의 계열에 속한다.

- 예제 코드에서 execlp("InternetBrowser", "0", NULL); 가 성공적으로 실행되면 자식 프로세스 코드가 새로운 프로세스로 대체되었기에, 하위 exit(0) 코드는 영영 실행되지 못하지만 실패 시에는 하위 코드가 실행된다.

 

좀비 프로세스는 무엇인가?

부모 프로세스가 자식 프로세스의 종료 상태를 수거하지 않아 남아있는 프로세스

- 실행되지 않은 채로 PCB만 남아있음

- 메모리를 계속 점유하고 있어, 시스템 자원을 낭비함

 

쓰레드는 어떤 정보를 포함하고 있는가?

TCB(Thread Control Block)에 쓰레드의 상태 및 제어 정보를 저장

1. TID & PID: 쓰레드 식별 고유 ID, 쓰레드가 속한 프로세스 ID

2. State: 쓰레드의 실행 상태 (`Running`, Waiting, Ready, Terminated)

3. Register Contents: 스위칭 복원을 위한 CPU 레지스터 정보

4. Program Counter: 쓰레드 마지막 명령어 주소

5. Stack Pointer: 쓰레드 스택에서 현재 실행 중인 함수 위치 포인터

6. Priority : 여러 쓰레드 동시 실행 시, 우선순위

 

댓글을 작성해보세요.

채널톡 아이콘