[혼공컴운] 4주차_chapter09~11

Erdos·2025년 7월 18일

혼공단

목록 보기
5/17
post-thumbnail

저자 github

4주차

  • Chapter 09 ~ 11
  • p. 304의 확인 문제 1번 풀고 인증하기
  • Ch.11(11-2) 준비 큐에 A,B,C,D 순으로 삽입되었다고 가정했을 때, 선입 선처리 스케줄링 알고리즘을 적용하면 어떤 프로세스 순서대로 CPU를 할당받는지 풀어보기

09 운영체제 시작하기


9-1 운영체제를 알아야 하는 이유

운영체제가 하는 일

1) 프로그램에 필요한 자원을 할당한다.
2) 프로그램이 올바르게 실행되도록 돕는다.

  • 각 응용프로그램의 메모리 주소가 겹치지 않도록 적당한 공간에 프로그램 적재.
  • 최대한 공정하게 CPU 자원 할당

3) 더 이상 실행되지 않는 프로그램을 메모리에 삭제하며 지속적으로 메모리 자원 관리

메모리

  • 커널 영역: 운영체제는 매우 특별한 프로그램. 항상 컴퓨터가 부팅될 때 따로 적재되어 실행된다.
  • 시스템 영역: 커널 영역을 제외한 나머지 영역, 사용자가 이용하는 응용 프로그램이 적재되어 있는 영역.

알아야 하는 이유

운영체제와의 대화를 통해 하드웨어와 프로그램을 더 깊이 이해하고 문제 해결의 실마리.

  • 운영체제는 프로그램을 위한 프로그램 이다.

9-2 운영체제의 큰 그림

커널

  • 운영체제의 심장
  • 운영체제의 핵심 기능을 담당하는 부분

운영체제에는 속하는데 커널에는 속하지 않는 기능

  • UI(User Interface): 사용자와 컴퓨터 간의 통로.
    • GUI(Graphic User Interface)
    • CLI(Command Line Interface)

이중 모드 (dual mode)

운영체제는 응용 프로그램들이 자원에 접근하려 할 때 오직 자신을 통해서만 접근하도록 하여 자원을 보호한다.
🚩 슈퍼바이저 플래그: 커널 모드로 실행 중인지(1) 사용자 모드로 실행 중인지(0)를 나타낸다. <- 플래그 레지스터에서

  • CPU가 명령어를 실행하는 모드를 크게 사용자 모드와 커널 모드로 구분하는 방식
  • 사용자 모드(user mode)
    • 운영체제 서비스를 제공받을 수 없는 실행 모드
    • 커널 영역의 코드를 실행할 수 없는 모드
    • 일반적인 응용 프로그램
    • 자원 접근 불가
  • 커널 모드(kernel mode)
    • 운영체제 서비스를 제공받을 수 있는 실행 모드
    • 커널 영역의 코드를 실행할 수 있는 모드
    • 운영체제
  • 시스템 호출(system call)

시스템콜 추적하기

#include <stdio.h>

int main()
{
        printf("hello world!\n");
        return 0;
}
# 컴파일 후, 터미널에서 실행파일 앞에 strace를 입력한다.
strace ./a.out
  • strace: 리눅스 시스템에서 프로세스와 커널 간의 상호 작용을 추적하는 데 사용되는 도구다. 시스템 호출, 시그널, 프로세스 상태 변화 등을 감시한다.

WOW

운영체제의 핵심 서비스

1) 프로세스 관리

  • 프로세스: 실행 중인 프로그램
  • CPU는 프로세스들을 조금씩 번갈아 가며 실행한다.
  • 이 후에 배울 것
    • 프로세스 동기화: 여러 프로세스가 동시에 실행되는 환경에서 필요한 것
    • 교착 상태: 프로세스가 꼼짝도 못하고 더이상 실행되지 못하는 상황

2) 자원 접근 및 할당

  • CPU
    • 한 번에 하나의 프로세스만 실행할 수 있다.
    • CPU 스케쥴링(어떤 프로세스부터? 얼마나 오래 이용하게 할지?)
  • 메모리: 페이징, 스와핑
  • 입출력장치

3) 파일 시스템 관리

  • 관련된 정보를 파일이라는 단위로 저장 장치에 보관
  • 파일들을 묶어 디렉터리 단위로 저장 장치에 보관

10 프로세스와 스레드


10-1 개요

프로세스 직접 확인하기

포그라운드 프로세스(foreground process)

사용자가 보는 앞에서 실행되는 프로세스
1) 윈도우에서는 .. 작업관리자->프로세스

2) 리눅스에서 ps -ef 명령어

ps: process status

  • -e(all): 시스템에 존재하는 모든 프로세스
  • -f(full): UID, PPID, C, TIME, CMD 등 상세한 필드까지 출력

백그라운드 프로세스(background process)

사용자와 상호작용하지 않고 그저 묵묵히 정해진 일만 수행하는 백그라운드 프로세스
1) 윈도우에서는 서비스

2) 유닉스에서는 데몬(daemon)

프로세스 제어 블록

  • 프로세스들은 돌아가면서 한정된 시간만큼만 CPU 이용
  • 이를 위해 사용하는 자료 구조가 프로세스 제어 블록(PCB)이다.
  • PCB: Process Control Block
    • 프로세스와 관련된 정보를 저장하는 자료 구조
    • 마치 상품에 달린 태그와 같음
    • 커널 영역에 생성됨

PCB에 담기는 정보

1) 프로세스 ID (PID:Process ID)

  • 특정 프로세스를 식별하기 위해 부여하는 고유한 번호

    🤔 책과 다르게 고유 번호가 아닌 프로세스 이름이 나오는 상황.
    작업관리자를 뒤적여보니 PID는 [자세히]에서 찾을 수 있다.

2) 레지스터 값: 프로세스는 자신의 실행차례가 오면 이전까지 사용한 레지스터 중간 값을 모두 복원하고 실행 재개
3) 프로세스 상태: 생성상태, 준비상태, 실행상태, 대기 상태, 종료 상태
4) CPU 스케줄링 정보: 프로세스가 언제 어떤 순서로 CPU를 할당받을지에 대한 정보
5) 메모리 관리 정보: 프로세스가 어느 주소에 저장되어 있는지. 페이지 테이블
6) 사용한 파일과 입출력장치 목록

리눅스에서 PCB 확인하기

// 예시 코드
#include <stdio.h>
#include <unistd.h>
int main() {
    printf("Hello, world!\n");
    sleep(60); // 60초 대기
    return 0;
}
# 위 코드를 cc 소스코드명.c 컴파일 하고
# 차례대로 실행하면 아래와 같이 나온다(그림 일부)
./a.out
ps -ef | grep a.out (3번째 컬럼이 PID)
cat /proc/PID/status

문맥 교환(context switching) ⭐⭐⭐

1) 기존 프로세스의 문맥을 PCB에 백업하고 새로운 프로세스를 실행하기 위해 문맥을 PCB로부터 복구하여 새로운 프로세스를 실행하는 것

  • 너무 자주 하면 오버헤드 발생

2) 프로세스 A에서 프로세스 B로 실행 순서가 넘어가면?

  • 프로세스 A는 지금까지의 중간 정보를 백업
    • 문맥(context): 프로그램 카운터 등 각종 레지스터 값, 메모리 정보, 열었던 파일, 사용한 입출력 장치 등
    • context를 백업해두면 언제든 해당 프로세스의 실행을 재개할 수 있다.
  • 프로세스 B 문맥 복구

프로세스의 메모리 영역

1) 코드 영역(텍스트 영역)

  • 기계어로 이루어진 명령어가 저장
  • read-only
  • 정적 할당 영역(크기가 고정된 영역)

2) 데이터 영역

  • 프로그램이 실행되는 동한 유지할 데이터가 저장되는 공간
    (프로그램이 실행되는 동안 유지할 데이터)
  • 예) 전역변수(global variable)
  • 정적 할당 영역(크기가 고정된 영역)

3) 힙 영역

  • 프로그래머가 직접 할당할 수 있는 저장 공간
  • 메모리 누수 발생: 프로그래밍 과정에서 힙 영역에 메모리 공간을 할당했다면, 언젠가는 해당 공간을 반환해야 한다. 하지만 반환하지 않는다면 메모리 낭비를 초래한다.
  • 동적 할당 영역(프로세스 실행 과정 중 크기가 변할 수 있는 영역)
  • 메모리가 낮은 주소에서 높은 주소로 할당

4) 스택 영역

  • 데이터를 일시적으로 저장하는 공간
  • 예) 매개 변수, 지역변수
  • 동적 할당 영역
    • 메모리가 높은 주소에서 낮은 주소로 할당

10-2 프로세스 상태와 계층 구조

프로세스 상태

PCB에 기록
1) 생성 상태(new): 곧바로 실행 x, 준비 상태가 되어 CPU 할당을 기다림
2) 준비 상태(ready): 기다리는 상태

  • 자신의 차례가 된다면 실행 상태로 전환되고 dispatch라고 함.

3) 실행 상태(running): 할당된 일정 시간 동안만 cpu 사용 가능. 할당된 시간을 모두 사용하면(타이머 인터럽트 발생) 다시 준비 상태가 됨. 실행 도중 임출력 장치의 작업이 끝날 때까지 기다려야 한다면 대기 상태가 됨.
4) 대기 상태(blocked): 일반적으로 프로세스 실행 도중 입출력 장치의 작업(느림)을 기다리는 상태
5) 종료 상태(terminated): 운영체제는 PCB와 프로세스가 사용한 메모리 정리

프로세스 상태 다이어그램

프로세스 계층 구조

  • 프로세스가 프로세스를 낳는 계층적인 구조(트리 구조)로써 프로세스들을 관리
  • 일부 운영체제에서는 자식 프로세스의 PCB에 부모 프로세스의 PID인 PPID(Parent PID)가 기록되기도 함
pstree # 프로세스의 계층 구조를 볼 수 있는 명령어

프로세스 생성 기법

1) fork

  • manual fork()
  • 자기 자신 프로세스의 복사본을 자식 프로세스로 생성하는 시스템 호출
  • 복사된 자식 프로세스라 하더라도 PID나 저장된 메모리 위치는 달라짐

2) exec

  • manual exec()
  • 자신의 메모리 공간을 다른 프로그램으로 덮어 쓰는 시스템 호출
  • 일종의 옷 갈아입기

10-3 스레드

프로세스를 구성하는 실행의 흐름 단위

프로세스와 스레드

  • 프로세스는 '실행의 흐름 단위가 하나'라는 점에서 단일 스레드 프로세스라고 볼 수 있다.
  • 전통적인 관점에서 하나의 프로세스는 한 번의 하나의 일만을 처리했다.
  • 스레드가 등장하면서 하나의 프로세스가 한 번에 여러 일을 동시에 처리할 수 있게 됨.
  • 프로세스와 스레드들은 실행에 필요한 최소한의 정보을 유지한 채 프로세스 자원을 공유하며 실행한다.
    • 프로그램 카운터를 포함한 레지스터, 스택
    • 그 프로세스의 자원을 공유할 수 있다

리눅스 창시자 Linus Torvalds의 '프로세스와 스레드'에 대한 반응

  • 96년 기록

multiprocess와 multithread

1) 멀티프로세스

  • 여러 프로세스를 동시에 실행하는 것
  • 프로세스끼리 자원 공유 x
  • 프로세스를 fork하면 코드/데이터/힙 영역 등 모든 자원이 복제되어 저장

    copy on write 기법: fork 직후 같은 프로세스를 통째로 메모리에 중복 저장하지 않으면서 동시에 프로세스끼리 자원을 공유하지 않는 방법이다.

    • fork() 함수 호출 시 부모와 자식 프로세스가 메모리를 공유하다가(read-only) 어느 한 쪽에서 데이터를 수정할 때 비로소 해당 메모리 영역을 복사하는 방식.
    • fork() 시스템 콜을 사용할 때 운영체제가 내부적으로 자동 적용하는 메모리 최적화 기법

2) 멀티스레드

  • 여러 스레드로 프로세스를 동시에 실행하는것
  • 같은 프로세스 내의 자원 공유
  • 하나의 스레드에 문제가 생기면 다른 스레드도 영향을 받음
  • 협력과 통신에 유리

프로세스 간의 통신

  • IPC(Inter-Process Communication): 프로세스끼리도 자원을 공유하고 데이터를 주고 받을 수는 있다. 스레드만큼 용이하지 않을 뿐!

프로세스 확인하기

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void foo() {
    printf("foo: child process: %d\n", getpid());
    printf("foo: parent process: %d\n", getppid());
}

int main() {
    printf("parent process: %d\n", getpid());

    int i = 0;
    while (i < 3) {
        pid_t pid = fork();
        if (pid == 0) {
            foo();
            return 0;
        }
        i++;
    }

    i = 0;
    while (i < 3) {
        wait(NULL);
        i++;
    }

    return 0;
}

11 CPU 스케쥴링


11-1 개요

CPU scheduling: 운영체제가 프로세스들에게 공정하고 합리적으로 CPU 자원을 배분하는 것

프로세스 우선순위

프로세스 종류

1) 입출력 집중 프로세스(I/O bound process)

  • 비디오 재생, 디스크 백업 등 입출력 작업이 많은 프로세스
  • 실행 상태보다 입출력을 위한 대기 상태에 더 많이 머무른다.
  • I/O burst가 많은 프로세스

2) CPU 집중 프로세스(CPU bound process)

  • 복잡한 수학 연산, 컴파일, 그래픽 처리 작업 등 CPU 작업이 많은 프로세스
  • 대기 상태보다 실행 상태에 더 많이 머무른다.
  • CPU burst가 많은 프로세스

💡일반적으로 입출력 집중 프로세스(완료 전까지 어차피 대기 상태)를 빨리 실행시키고 그 다음으로 CPU 집중 프로세스에 CPU를 집중적으로 할당하는 것이 더 효율적이다.

  • 명령을 통해 일부 프로세스의 우선 순위를 변경할 수 있음

ps -el

필드명설명
F플래그(Flags): 프로세스 상태를 나타내는 비트 플래그
S상태(Status): 프로세스의 상태(R: running, S: sleeping, Z: zombie 등)
UID프로세스 소유자(사용자 ID)
PID프로세스 ID
PPID부모 프로세스 ID
CCPU 사용률
PRI우선순위(priority)
NInice 값(프로세스의 우선순위 조정값)
ADDR메모리 주소(일부 시스템에서만 표시)
SZ가상 메모리 사이즈(단위: KB)
WCHAN프로세스가 대기 중인 커널 함수 이름
TTY연결된 터미널
TIME누적 CPU 시간
CMD실행된 명령어

-e : --everyone
-l: display the long format

스케쥴링 큐

  • Scheduling queue: 운영체제가 '줄을 서시오~.'
    CPU를 사용하고 싶은 프로세스들, 메모리에 적재되고 싶은 프로세스들, 특정 입출력 장치를 사용하고 싶은 프로세스들을 모두 줄을 세운다.
  • 반드시 선입선출 방식 x

큐의 종류

  1. ready queue: CPU를 이용하고 싶은 프로세스들이 서는 줄
  2. waiting queue: 입출력장치를 이용하기 위해 대기 상태에 접어든 프로세스들이 서는 줄. 같은 장치를 요구한 프로세스들은 같은 큐에서 대기

선점형과 비선점형 스케쥴링

1) 선점형 스케쥴링(preemptive scheduling)

  • 선점: 남보다 앞서 차지함
  • 운영체제가 프로세스로부터 자원을 강제로 빼앗아 다른 프로세스에 할당할 수 있는 스케줄링 방식
  • 자원 독점을 막고 골고루 배분 가능
  • 문맥 교환 과정에서 오버헤드가 발생할 수 있음

2) 비선점형 스케줄링(non-preemptive scheduling)

  • 자원을 이용하고 있는 프로세스가 종료 또는 스스로 대기 상태에 들어가기 전까지 다른 프로세스가 끼어들 수 없는 스케줄링
  • 문맥 교환 과정에서 오버헤드가 발생할 경우가 적음
  • 새로운 프로세스가 무작정 기다림
  • 자원 배분 x

11-2 CPU 스케쥴링 알고리즘

이것도 상황에 따라 구현하게 될 수도 있는 건가...? 🤔

종류

1) 선입 선처리 스케줄링(First Come First Served Scheduling)

  • FCFS 스케줄링
  • CPU를 먼저 요청한 프로세스부터 CPU를 할당하는 방식
  • 기다리는 시간이 매우 길어질 수 있음
  • 비선점형

2) 최단 작업 우선 스케줄링(Shortest Job First Scheduling)

  • SJF 스케줄링
  • CPU 사용 시간이 긴 프로세스는 나중에, 짧은 건 먼저
  • 기본은 비선점형 스케줄링 알고리즘이지만, 선점형으로도 구현 가능

3) 라운드 로빈 스케줄링(round robin schduling)

  • 선입 선처리 스케줄링 + 타임 슬라이스(time slice: 정해진 시간만큼만)
  • 정해진 타임 슬라이스만큼의 시간동안만 CPU를 이용하는 선점형 스케줄링
  • 타임 슬라이스 크기가 중요함

4) 최소 잔여 시간 우선 스케줄링(Shortest Remaining Time)

  • SRT 스케줄링
  • 최단 작업 우선 스케줄링 + 라운드 로빈 알고리즘
  • 정해진 시간만큼 CPU를 이용하되, 다음으로 CPU를 사용할 프로세스로는 남은 작업 시간이 가장 적은 프로세스 선택

5) 우선 순위 스케줄링(priority scheduling)

  • 최단 작업 우선 스케줄링, 최소 잔여 시간 스케줄링 ⊂ 우선순위 스케줄링
  • 문제점: starvation 현상 - 우선 순위 높은 프로세스만 주구장창 실행
  • 기아 현상을 방지하기 위한 기법
    - aging: 오랫동안 대기한 프로세스의 우선순위를 점차 높이는 방식

6) 다단계 큐 스케줄링(multilevel queue scheduling)

  • 우선 순위 스케줄링의 발전 형태
  • 우선 순위별로 준비 큐를 여러 개 사용하는 스케줄링 방식
  • 유형별로 처리하기가 용이함
  • but, 우선순위 큐 별로 이동이 불가하기 때문에 기아 현상이 일어날 수 있다.

7) 다단계 피드백 큐 스케줄링(mulilevel feedback queue scheduling)

  • 다단계 큐 스케줄링의 발전된 형태
  • 프로세스들이 큐 사이를 이동할 수 있다.
  • 에이징 기법 적용 가능
  • 즉, 어떤 프로세스의 CPU 시간이 길면 우선순위가 낮아지고 어떤 프로세스가 낮은 우선순위 큐에서 너무 오래 기다리면 우선 순위를 높이는 방식
  • CPU 스케쥴링의 가장 일반적인 형태

숙제


숙제 1: p. 304의 확인 문제 1번 풀고 인증하기

1) 생성상태
2) 준비상태
3) 실행상태
4) 종료상태
5) 대기상태

추가 숙제: Ch.11(11-2) 준비 큐에 A,B,C,D 순으로 삽입되었다고 가정했을 때, 선입 선처리 스케줄링 알고리즘을 적용하면 어떤 프로세스 순서대로 CPU를 할당받는지 풀어보기

A-B-C-D 순으로

profile
수학을 사랑하는 애독자📚 Stop dreaming. Start living. - 'The Secret Life of Walter Mitty'

0개의 댓글