반응형

Github Actions란?

Github에서 제공하는 CI/CD 등을 위한 서비스로 자동으로 코드 저장소에서 어떤 Event가 발생했을 때 작업(Workflow)이 일어나게 하거나 주기적으로 반복해서 실행시킬 수 있도록 도와주는 서비스

다양한 예시

  • 레포지토리에 코드가 푸쉬되었을 때 자동으로 Test Code 검사
  • 깃헙 레포에서 다양한 사람들과 협업할 때 coding convention (ex) code formatting)을 잘 맞췄는지 체크
  • Pull request가 merge되었을 때 docker image를 빌드하고 자동으로 Amazon Elastic Container Registry(ECR) 에 올리기

본 글에서는 Github actions를 통해 repository에 pushpull_request가 발생할 때마다 Python 코드의 formatting을 체크하는 black을 실행시켜 주기적으로 검사하는 작업을 위한 yaml 파일을 설명

예시를 통해서 Github Actions가 어떻게 작동하는지 알아봄

Black formatter yml파일 예시

Github actions는 yaml파일을 통해 서비스를 실행시킬 수 있다

main branch (default branch)에 .github/workflows 폴더 추가 후 아래 내용을 yaml 파일에 추가 (ex) black.yml)

name: black formatter # github action 이름

on:
  push: # 모든 branch에 commit이 push 될때 아래 workflow(jobs) 실행
    branches:
      - '*'
  pull_request:# 모든 branch에 pull_request 요청이 왔을 때 workflow(jobs) 실행
    branches:
      - '*'

jobs:
  Black_code_formatter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: psf/black@stable
        with:
          options: "-l 79 --diff --check"
          src: "./"

위의 yaml 파일 내용 설명

1) name

- name: black formatter
  • Github actions에서 workflow의 이름
    • workflow: 하나 이상의 job을 실행시키는 자동화된 process. 여러개의 job을 묶은거라 생각하면 되고 job은 아래에 다시 설명

왼쪽 빨간 박스처럼 이름이 표시됨

 

2) on push

- name: black formatter

- on:
    push: # commit을 push 했을 때 github action이 돌게한다

  • ‘어떤 event가 발생했을 때’ 에 해당
  • 가능한 event 종류들
    • push, pull_request, create 등등 (링크)

3) branches

name: black formatter # github action 이름

on:
  push:
    branches:
      - '*'
  • “어떤 branch”에 코드가 push 된 경우에 workflow를 실행할지 결정
  • 위의 예는 모든 branch( * 로 표시)에 push되는 경우이고, 아래처럼 특정 branch에 push될 때를 지정할 수 있음
on:
  push:
    branches:
      - 'develop'

4) on pull_request branches

name: black formatter # github action 이름

on:
  push:
    branches:
      - '*'
  pull_request:
    branches:
      - '*'
  • 위는 모든 branch에 pull_request가 열렸을 때 workflow를 실행한다는 의미
  • 참고
    • 각 event (ex) pull_request) 마다 types(ex) opened review_requested, closed) 이 있음
    • 아래와 같이 types를 지정해줄 수 있음 (pull_request는 default type이 opened)
    on:
      pull_request:
        types: [opened, reopned]
    
    

5) jobs & each job name

  • workflow는 하나 이상의 job 들로 구성되는데 jobs에 대해 설정

기본형태

jobs:
  <job_id_1>: # job1의 이름 (github UI에 표시됨)

  <job_id_2>: # job2의 이름
name: black formatter # github action 이름

on:
  push:
    branches:
      - '*'
  pull_request:
    branches:
      - '*'

jobs:
  Black_code_formatter:

6) runs-on

  • 어떤 형태의 os 에서 job이 실행될지를 정의 (기본적으로 github이 제공하는 virtual machine)
    • window, ubuntu, macOS
name: black formatter # github action 이름

on:
  push:
    branches:
      - '*'
  pull_request:
    branches:
      - '*'

jobs:
  Black_code_formatter:
    runs-on: ubuntu-latest
  • github이 제공하는 ubuntu-lateast 를 image로 사용

7) steps

  • 각각의 job은 steps 라고 하는 연속된 task들로 구성됨
  • command를 실행할 수 있고, setup task 도 실행할 수 있음
  • 예시
steps:
  run: echo 'Hello'
name: black formatter

on:
  push: #
    branches:
      - '*'
  pull_request:
    branches:
      - '*'

jobs:
  Black_code_formatter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: psf/black@stable
        with:
          options: "-l 79 --diff --check"
          src: "./"

8) uses

  • job에서 steps의 일부로서 action을 선택하는 명령어
  • 아래 예는 public action을 사용
name: black formatter

on:
  push:
    branches:
      - '*'
  pull_request:
    branches:
      - '*'

jobs:
  Black_code_formatter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: psf/black@stable
        with:
          options: "-l 79 --diff --check"
          src: "./"

public action을 사용하는 예

9) with

  • uses 키워드 옆의 각각의 action들에 대해 정의된 input parameter map 을 아래에 입력하게하는 키워드
name: black formatter

on:
  push: 
    branches:
      - '*'
  pull_request:
    branches:
      - '*'

jobs:
  Black_code_formatter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: psf/black@stable
        with:
          options: "-l 79 --diff --check"
          src: "./"

  • black formatter는 options 키워드와 src 키워드를 이용해 argument를 넘겨줄 수 있음 (링크)

options

  • -l 79 : 한줄에 혀용되는 character 수로 79자로 설정 (default 88)
  • --diff : 파일을 수정하진 않고 수정되어야 할 부분을 로그로 알려주고 수정될 형태를 제안
  • --check : 파일을 수정하진 않고 status code를 반환
    • status code 0: formatting 되어야 할 부분 없음
    • status code 1: formatting 되어야 할 부분 있음
    • status code 123: code error (internal error)

src

  • “./” : 전체 코드에 대해서 formatting 확인

위의 yaml 파일을 repo에 추가하면 아래와 같이 Workflow가 생성되어 작동되는걸 확인할 수 있음

 

초록색 체크표시는 성공적으로 완료된 상태

해당 워크플로우를 눌러보면 우리가 위에서 작성했던 Job의 이름이 표시되고 job을 누르면 구체적으로 어떤 step들이 실행되었는지 표시된다

반응형
반응형

본 글은 책 "혼자 공부하는 컴퓨터 구조+운영체제" 의 Chapter 15. 파일시스템 부분을 읽고 정리한 내용입니다.

파일

  • 하드 디스크나 SSD 같은 보조기억장치에 저장된 관련 정보의 집합, 관련있는 정보를 모은 논리적 단위

파일을 이루는 정보

  • 이름
  • 파일을 실행하기 위한 정보
  • 파일 관련 부가 정보 (속성, 메타데이터)
    • 파일 형식, 위치, 크기 등
 

파일 속성과 유형

속성 이름  의미
유형 운영체제가 인지하는 파일의 종류 (텍스트, 실행, 음성)
크기 현재크기 & 허용 가능한 최대 크기
보호 어떤 사용자가 파일을 읽고/쓰고/실행할 수 있는지
생성 날짜 ...
마지막 접근 날짜  
마지막 수정 날짜  
생성자  
소유자  
위치  

* 속성 이름 자체가 의미를 담고 있는 내용인 경우는 생략

파일 유형

  • 확장자를 이용해 유형을 나타냄

 

파일 연산을 위한 시스템 호출

  • 파일을 다루는 모든 작업은 운영체제에 의해 이뤄지고 응용프로그램은 파일을 조작할 수 없음

파일 연산을 위한 시스템 호출

  • 생성, 삭제, 열기, 닫기, 읽기 ,쓰기

디렉토리

  • 파일들을 정리하기 위해 사용되고 윈도우에서는 폴더라고 부름

옛 운영체제에서는 하나의 디렉토리만 존재했음 (single-level directory)

 

이후, 여러 계층을 가진 tree-structured directory가 생겨남

최상위 디렉토리(root directory, '/'로 표현) 아래 여러 서브 디렉토리가 있을 수 있음

 

절대 경로와 상대 경로

  • 절대 경로: 루트 디렉토리에서 자기 자신까지 이르는 고유한 경로
    • /home/minchul/a.sh
  • 상대 경로: 현재 디렉토리부터 시작하는 경로
    • 현재 디렉토리 경로가 /home이라면 a.sh의 상대 경로는 minchul/a.sh

디렉토리 연산을 위한 시스템 호출

  • 디렉토리 생성, 삭제, 열기, 닫기, 읽기

디렉토리 엔트리

  • 많은 운영체제에서 디렉토리를 그저 ‘특별한 형태의 파일’로 간주
  • 디렉토리는 보조기억장치에 테이블 형태의 정보로 저장되는데 각각의 행을 디렉토리 엔트리라고 함
파일 이름  위치를 유추할 수 있는 정보
   

파일 시스템에 따라 디렉터리 엔트리에 파일 속성을 명시하는 경우도 있음

파일 이름 위치를 유추할 수 있는 정보 생성 시간 수정된 시간     크기
         

 

예시

 

home 디렉토리는 대략 다음과 같이 구성됨

파일 이름  위치를 유추할 수 있는 정보
.. (상위 디렉토리)  
. (현재 작업 디렉토리)  
minchul  
guest  

minchul 디렉토리 엔트리에는 디렉토리에 포함된 파일들의 이름(a.sh, b.c, c.tar)과 이들의 위치를 알 수 있는 정보들이 포함되어있음

 

파일 시스템

  • 파일과 디렉토리를 보조기억장치에 일목요연하게 저장하고 접근할 수 있게 하는 운영체제 내부 프로그램

파티셔닝과 포매팅

  • 보조기억장치를 사용하려면 파티션을 나누는 작업과 포맷 작업을 거쳐야 함
  • 파티셔닝: 저장 장치의 논리적인 영역을 구획하는 작업 (일종의 칸막이로 영역을 나누는 작업)
    • 파티션: 파티셔닝 작업으로 나눠진 영역 하나하나
  • 포매팅: 파일 시스템을 설정하여 어떤 방식으로 파일을 저장하고 관리할 것인지를 결정하고 새로운 데이터를 쓸 준비를 하는 작업

Windows에서 USB의 파일 시스템 예시

  • 포매팅 할 때 파일 시스템이 결정됨
  • 파일 시스템은 여러 종류가 있고 파티션마다 다른 파일 시스템을 설정할 수도 있음

 

파일 할당 방법

  • 운영체제는 파일과 디렉토리를 블록(block) 단위로 읽고 씀
    • 하나의 파일이 보조기억장치에 저장될 떄 하나 이상의 블록에 걸쳐 저장됨
  • 하드 디스크의 가장 작은 저장단위는 섹터지만 운영체제는 하나 이상의 섹터를 블록이라는 단위로 묶어 관리

  • 하드 디스크내에 여러 블록이 있음

 

파일을 보조기억장치에 할당하는 방법

  1. 연속 할당
  2. 불연속 할당
    • 연결 할당
    • 색인 할당

 

연속 할당(contiguous allocation)

  • 가장 단순한 방식
  • 블록을 3, 2, 5개 차지하는 정도의 크기를 가진 파일 a, b, c가 있다면 아래처럼 할당

  • 연속으로 할당된 파일에 접근하기 위해서는 파일의 첫번째 블록 주소와 블록 단위의 길이만 알면됨

 

  • 연속 할당을 사용하는 파일 시스템에서는 디렉토리에 엔트리에 파일 이름과 더불어 첫번째 블록 주소와 블록 단위의 길이를 명시

장점

  • 구현이 단순

단점

  • 외부 단편화를 야기할 수 있음

 

단점 예시

위의 사진과 같이 파일이 연속할당방식으로 저장된 상황에서 파일 D, F가 삭제 된다면?

  • 블록은 총 11개가 남지만, 크기가 블록 7개 이상을 사용하는 파일은 할당될 수 없음

 

연결 할당(linked allocation)

  • 불연속 할당의 종류
  • 파일을 이루는 데이터를 linked list로 관리

  • 4개의 블록으로 구성된 a라는 파일이 있다고 할 때
  • 10→5→13→2 순으로 블록이 연결되어 있고 2번 블록에는 다음 블록이 없다는 특별한 표시자(-1)를 기록

 

  • 디렉토리 엔트리에는 파일 이름과 함께 첫번째 블록 주소와 블록 단위의 길이를 명시

길이가 아닌 마지막 블록의 주소를 기록할 수도 있음

단점

1. 반드시 첫번째 블록부터 하나씩 차례대로 읽어야 함

  • 파일 내 임의의 위치에 접근하는 속도(random access 속도)가 매우 느려 성능면에서 비효율적

2. 하드웨어 고장이나 오류 발생 시 해당 블록 이후 블록은 접근할 수 없음

  • 하나의 블록 안에 파일 데이터와 다음 블록 주소가 모두 포함되어 있다보니, 파일을 이루는 블록에 하나라도 문제가 발생하면 이후 블록에 접근할 수 없음

 

색인 할당(indexed allocation)

  • 파일의 모든 블록 주소를 색인 블록(index block)이라는 하나의 블록에 모아 관리하는 방식

색인 할당 예시

  • 파일 a의 색인 블록은 4번 블록
  • 파일의 데이터는 7, 13, 11 블록이 저장되어 있다고 가정
  • 파일 a에 순차적으로 접근하고 싶다면 생인 블록에 저장된 주소로 차례대로 접근하면 됨

 

  • 임의의 위치에 접근하고 싶다면 색인 블록의 i번째 항목이 가리키는 블록에 접근하면 됨
  • 디렉토리 엔트리에는 파일 이름과 색인 블록 주소를 명시

색인 할당을 기반으로 만든 파일 시스템이 유닉스 파일 시스템

 

파일 시스템 살펴보기

대표적인 파일 시스템 2가지

  1. FAT 파일 시스템: USB, SD 카드등의 저용량 저장 장치에 사용됨
  2. 유닉스 파일 시스템:유닉스 계열 OS에 사용됨

FAT 파일 시스템 (File Allocation Table)

  • 연결 할당 기반 파일 시스템의 단점을 보완
    • 단점의 근본적인 원인은 블록 안에 다음 블록의 주소를 저장했기 때문

 

각 블록에 포함된 다음 블록의 주소들을 한데 모아 테이블 형태로 관리하면? 파일 할당 테이블(FAT)!

  • 파일의 첫번째 블록 주소(4번블록)만 알면 4→8→3→5 순으로 파일의 데이터가 담긴 모든 블록에 접근할 수 있음
  • 이렇게 FAT을 이용하는 파일 시스템이 바로 FAT 파일 시스템
  • MS-DOS에서 사용되었고 최근까지 저용량 저장 장치용 파일 시스템으로 많이 사용됨
  • 버전에 따라 FAT12, 16, 32가 있으며 숫자는 블록을 표현하는 비트수를 의미

FAT(FAT12) 파일 시스템을 사용하는 파티션 도식도

  • FAT 영역: FAT가 저장되고 파티션의 앞부분에 만들어짐
  • 루트 디렉토리 영역: 루트 디렉토리가 저장되는 영역
  • 데이터 영역: 서브 디렉토리와 파일들을 위한 영역

FAT가 메모리에 캐시될 경우 느린 임의 접근 속도도 개선 가능

FAT파일 시스템의 디렉토리 엔트리

시작 블록을 통해 FAT에서 해당 파일의 내용들에 접근할 수 있음

  • 속성은 읽기전용/숨김 파일/시스템 파일/ 일반 파일/ 디렉토리 등을 식별하기 위한 항목

아래 디렉토리 구조를 이루는 FAT 파일 시스템에서 /home/minchul/a.sh 파일을 읽는 과정

 

/home/minchul/a.sh 에 접근하는 과정

  1. 루트 디렉토리에서 home 디렉토리는 몇번 블록에 있는지 살펴봄 → 3번 블록
  2. 3번 블록을 읽어 home 디렉토리 내용을 살펴보고 minchul 디렉토리가 몇번 블록에 있는지 살펴봄 → 15번
  3. 15번 블록을 읽어 a.sh 파일의 첫번째 블록 주소를 확인 → 9번
  4. FAT을 통해 9→8→11→13 블록 순서로 a.sh 파일 내용에 접근 가능

 

유닉스 파일 시스템

  • 색인 할당 기반의 파일 시스템
  • 색인 블록 == i-node
    • 파일의 속성 정보와 15개의 블록 주소가 저장될 수 있음

  • 파일마다 i-node를 가지고 있고 i-node 마다 고유한 번호가 부여되어있음

 

UNIX 파일 시스템을 사용하는 파티션 도식도

  • 파티션 내에 i-node 영역에 i-node들이 있고 데이터 영역에 디렉토리와 파일들이 있음

 

문제: i-node의 크기는 유한한데 블록을 20개, 30개, 그 이상 차지하는 파일은?

첫째, 블록 주소 중 12개에는 직접 블록 주소를 저장

  • i-node가 가리킬 수 있는 열다섯 개의 블록 주소 중 처음 12개에는 파일 데이터가 저장된 블록 주소를 직접 명시
    • direct block: 파일 데이터가 저장된 블록

 

둘째, ‘첫째’ 내용으로 충분하지 않다면 13번째 주소에 단일 간접 블록 주소를 저장

  • 단일 간접 블록(single indirect block): 파일 데이터가 저장된 블록 주소가 아닌 파일 데이터를 저장한 블록 주소가 저장된 블록을 의미

 

 

셋째, ‘둘째’ 내용으로 충분하지 않다면 14번째 주소에 이중 간접 블록 주소를 저장

  • 이중 간접 블록(double indirect block): 데이터 블록 주소를 저장하는 블록 주소가 저장된 블록

넷째, ‘셋째’ 내용으로 충분하지 않다면 열다섯 번째 주소에 삼중 간접 블록 주소를 저장

삼중 간접 블록: 이중 간접 블록 주소가 저장된 블록

 

unix 파일 시스템의 디렉토리 엔트리도 파일 이름과 i-node 번호로 구성됨

UNIX 파일 시스템의 디레고리 엔트리

 

예시

  • 유닉스 파일 시스템에서 /home/minchul/a.sh 파일을 읽는 과정

 

  • 루트 디렉토리 위치는 루트 디렉토리의 i-node를 통해 확인
    • 유닉스 파일 시스템은 루트 디렉토리의 i-node를 항상 기억하고 있음
    • 2번 i-node가 루트 디렉토리의 i-node라고 가정
  1. i-node 2를 통해 루트 디렉토리 위치 파악 → 1번 블록
  2. 1번 블록을 읽으면 루트 디렉토리 내용을 알 수 있음 → home 디렉토리의 i-node 번호는 3
  3. i-node 3에 접근하여 home의 디렉토리 위치 파악 →210번 블록
  4. 210번 블록을 읽으면 home 디렉토리 내용을 알 수 있음 → minchul의 i-node 번호는 8
  5. i-node 8에 접근하면 minchul 폴더의 위치 파악 → 121번 블록
  6. 121번 블록을 읽으면 minchul 디렉토리 내용을 알 수 있음 → a.sh 파일의 i-node 번호는 9번
  7. i-node 9에는 98, 12, 13 블록이 있음

⇒ 결론적으로 a.sh 파일을 읽기 위해 98→12→13 블록에 접근하면 됨, i-node를 통해 위치 정보를 알고, 블록을 통해 내용을 알 수 있음

 

 

반응형

'OS' 카테고리의 다른 글

블로킹/논블로킹  (0) 2024.08.10
동기/비동기  (0) 2024.08.10
가상 메모리(Virtual memory)  (0) 2024.07.28
교착상태(Deadlock)  (0) 2024.07.19
프로세스 동기화  (0) 2024.07.19
반응형

본 글은 책 "혼자 공부하는 컴퓨터 구조+운영체제" 의 Chapter 14. 가상메모리 부분을 읽고 정리한 내용입니다.

연속 메모리 할당

  • 프로세스에 연속적인 메모리 공간을 할당

스와핑

  • 현재 사용되지 않는 프로세스들을 보조기억장치의 일부 영역으로 쫓아내고 생긴 빈공간에 새로운 프로세스를 적재

  • swap space: 프로세스들이 쫓겨나는 보조기억장치의 일부 영역
  • swap-out: 현재 실행되지 않는 프로세스가 메모리에서 스왑 영역으로 옮겨지는 것
  • swap-in: 스왑 영역에 있던 프로세스가 다시 메모리로 옮겨 오는 것

스와핑을 이용하면 실제 메모리 크기보다 프로세스들이 요구하는 메모리 공간 이 더 크더라도 동시에 실행할 수 있음

 

스왑 영역 크기 확인하기 (mac): sysctl vm.swapusage

$ sysctl vm.swapusage
vm.swapusage: total = 4096.00M  used = 2755.62M  free = 1340.38M  (encrypted)

 

메모리 할당

  • 프로세스는 메모리의 빈 공간에 할당되어야 하는데 여러개라면?
  • 최초 적합, 최적 적합, 최악 적합

  • 빈공간 A, B, C가 있다면?

최초 적합(first-fit)

  • 운영체제가 메모리 내의 빈 공간을 순서대로 검색하다 적재할 수 있는 공간을 발견하면 그 공간에 프로세스를 배치하는 방식
    • 순서대로 검색한다는 의미는? 어디서부터 검색?
  • 검색 최소화, 빠른 할당

최적 적합(best-fit)

  • 운영체제가 빈 공간을 모두 검색해본 뒤, 적재 가능한 가장 작은 공간에 배치

최악 적합(worst fit)

  • 운영체제가 빈 공간을 모두 검색해본 뒤, 적재 가능한 가장 큰 공간에 프로세스를 배치

 

외부 단편화(external fragmentation)

  • 프로세스들이 실행&종료 되길 반복하며 메모리 사이사이에 빈 공간이 발생해서 메모리가 낭비되는 현상

 

외부 단편화를 해결할 수 있는 대표적인 방법들

  1. 메모리 압축
  • 여기저기 흩어져 있는 빈 공간들을 하나로 모으는 방식

단점

  1. 작은 빈 공간들을 하나로 모으는 동안 시스템은 하던 일을 중지해야하고, 메모리에 있는 내용들을 옮기는 작업은 많은 오버헤드를 야기
  2. 프로세스 이동 방법에 대한 방법을 결정하기 어려움
  3. 물리 메모리보다 큰 프로세스 실행 불가

 

페이징을 통한 가상 메모리 관리

가상 메모리

  • 실행하고자 하는 프로그램의 일부만 메모리에 적재하여 실제 물리 메모리 크기보다 더 큰 프로세스를 실행할 수 있게 하는 기술

페이징이란?

  • 프로세스를 일정 크기로 자르고, 이를 메모리에 불연속적으로 할당하는 메모리 관리 기법

  • 논리 주소 공간을 페이지(page)라는 일정 단위로 자르고,
  • 메모리의 물리 주소 공간을 프레임(frame)이라는 페이지와 동일한 일정한 단위로 자른 뒤
  • 페이지를 프레임에 할당하는 가상 메모리 관리 기법

 

페이지 교체와 프레임 할당

요구 페이징(Demand paging)

  • 프로세스를 메모리에 적재할 때 처음부터 모든 페이지를 적재하지 않고 필요한 페이지만을 메모리에 적재하는 기법

기본적인 양상

  1. CPU가 특정 페이지에 접근하는 명령어를 실행
  2. 해당 페이지가 현재 메모리에 있을 경우(유효 비트가 1인 경우) CPU는 페이지가 적재된 프레임에 접근
  3. 해당 페이지가 현재 메모리에 없을 경우(유효비트가 0인 경우) 페이지 폴트가 발생
  4. 페이지 폴트 처리 루틴은 해당 페이지를 메모리에 적재하고 유효 비트를 1로 설정
  5. 다시 위의 1번을 수행

* 순수 요구 페이징(pure demand paging)

  • 아무런 페이지도 메모리에 적재하지 않은 채 무작정 실행부터 하는 기법
  • 프로세스의 첫 명령어를 실행하는 순간부터 페이지 폴트가 계속 발생함
  • 실행에 필요한 페이지가 어느 정도 적재된 이후부터는 페이지 폴트 발생 빈도가 떨어짐

 

요구페이징이 안정적으로 작동하기 위해서는 아래의 2가지가 해결되어야 함

  • 페이지 교체
  • 프레임 할당

 

페이지 교체

  • 요구 페이징 기법으로 페이지들을 적재하다보면 언젠가 메모리가 가득 차게 됨
  • 당장 실행에 필요한 페이지를 적재하려면 페이지를 보조 기억장치로 보내야 하는데 이를 결정하는 방법이 페이지 교체 알고리즘

 

페이지 교체 알고리즘

  • 일반적으로 페이지 폴트가 가장 적제 발생하는 알고리즘을 좋은 알고리즘으로 평가
    • 페이지 폴트가 일어나면 보조기억장치로부터 필요한 페이지를 가져와야하기 때문에 성능 저하발생하기 떄문

페이지 폴트 횟수를 어떻게 알 수 있을까?

⇒ 페이지 참조열 (page reference string) 사용

CPU가 참조하는 페이지들중 연속된 페이지를 생략한 페이지열 (연속된 페이지 참조에서는 페이지 폴트가 발생하지 않기 때문)

예를 들어 아래 숫자들의 페이지 번호들을 CPU가 참조했다면,

2 2 2 3 5 5 5 3 3 7

연속된 페이지를 생략한 페이지 참조열은 아래와 같음

2 3 5 3 7

 

FIFO 페이지 교체 알고리즘

  • First-In, First-Out Page Replacement Algorithm
  • 메모리에 가장 먼저 올라온 페이지부터 내쫓는 방식

  • 페이지가 초기에 적재될 때 발생할 수 있는 페이지 폴트는 고려하지 않음

단점

  • 프로그램 실행 내내 사용될 내용을 포함할 수도 있는데 이런 페이지를 메모리 메모리에 먼저 적재되었다고 내쫓을 수 있음

 

2차 기회(second-chance) 페이지 교체 알고리즘

  • 참조 비트 1인 경우: 한번 더 기회를 주기
    • 참조 비트 0으로 초기화 후 적재 시간을 현재 시간으로 설정
  • 참조 비트 0인 경우: CPU가 참조한 적이 없는 페이지로 바로 내쫓기

 

페이지 3의 참조 비트가 1인 경우

 

페이지 3의 참조비트를 0으로 초기화 후 가장 최근에 적재된 페이지로 간주

 

최적 페이지 교체 알고리즘(Optimal p age replacement algorithm)

  • CPU에 의해 참조되는 횟수를 고려하는 페이지 교체 알고리즘
  • 앞으로 사용빈도가 가장 낮은 페이지를 교체하는 방식
2 3 1 3 5 2 3 4 2 3

  • 첫 페이지 폴트: 페이지 1의 경우 한번 사용된 후 이후에 사용되지 않기 때문에 이를 교체함
  • 두번째 페이지 폴트: 2,3,5 페이지가 적재된 상황에서 4 페이지를 적재해야 할 때, 그 이후 페이지 2, 3이 사용되므로 5를 교체

특징

  • 가장 낮은 페이지 폴트율을 보장하는 알고리즘
  • 앞으로 사용되지 않을 페이지 예측관련해 실제 구현이 어려움
  • 다른 페이지 교체 알고리즘 성능을 평가하기 위한 하한선으로 간주

 

LRU 페이지 교체 알고리즘

  • Least Recently Used Replacement Algorithm
  • 가장 오래 사용되지 않은 페이지 교체

첫 페이지 폴트

  • 페이지 2, 3, 1이 적재된 상태
  • 페이지 5를 적재하려는 상황에서 최근에 페이지 1, 3, 이 적재되었으므로 페이지 2를 교체

두번째 페이지 폴트

  • 페이지 5, 3, 1이 적재된 상태
  • 페이지 2를 적재하려는 상황에서 최근에 페이지 5, 3, 이 적재되었으므로 페이지 1을 교체

세번째 페이지 폴트

  • 페이지 5, 3, 2가 적재된 상태
  • 페이지 4를 적재하려는 상황에서 최근에 페이지 2, 3 이 적재되었으므로 페이지 5를 교체

 

스래싱과 프레임 할당

페이지폴트가 자주 발생하는 이유

  1. 나쁜 페이지 교체 알고리즘
  2. 프로세스가 사용할 수 있는 프레임 자체가 적어서
  • 새로운 페이지를 참조할 때마다 페이지 폴트가 발생 → 저조한 CPU 이용율

 

스래싱(Thrashing)

  • 프로세스가 실제 실행되는 시간보다 페이징에 더 많은 시간을 소요하여 성능이 저해되는 문제

  • 동시에 실행되는 프로세스의 수를 늘린다고 CPU의 이용률이 높아지는 것은 아님

* 멀티프로그래밍의 정도: 메모리에 동시에 실행되는 프로세스의 수

  • 각 프로세스가 필요로 하는 최소한의 프레임 수가 보장되지 않았기 때문에 발생
  • 각 프로세스가 필요로 하는 최소한의 프레임 수를 파악하고 프로세스들에게 적절한 프레임을 할당해주어야 함

 

프레임 할당 방식

  1. 균등 할당(equal allocation)
  • 가장 단순한 할당 방식
  • 모든 프로세스들에게 균등하게 프레임을 할당하는 방식
    • 300개의 프레임을 3개의 프로세스에 할당 시 각 프로세스에 100개의 프레임을 할당
  • 실행되는 프로세스들의 크기를 고려하지 못한 방식

 

2. 비례 할당(proportional allocation)

  • 프로세스의 크기에 비례하여 프레임 할당

참고) 균등할당과 비례 할당은 프로세스의 실행 과정을 고려하지 않고 단순히 프로세스의 크기와 물리 메모리의 크기만을 고령한 방식이라는 점에서 정적 할당 방식이라고 함

 

프로세스를 실행하는 과정에서 배분할 프레임을 결정하는 방식의 종류

  1. 작업 집합 모델(working set model)
  • 작업집합: 실행 중인 프로세스가 일정 시간 동안 참조한 페이지의 집합
  • 프로세스가 일정기간동안 참조한 페이지 집합을 기억하여 빈번한 페이지 교체를 방지
  1. 페이지 폴트 빈도(PFF: Page-Fault Frequency)

아래 2가지 가정에서 생겨난 아이디어

  1. 페이지 폴트율이 너무 높으면 프로세스는 너무 적은 프레임을 갖고 있다
  2. 페이지 폴트율이 너무 낮으면 프로세스는 너무 많은 프레임을 갖고 있다
  • 상한선, 하한선 범위 안에서만 프레임을 할당하는 방식

 

참고

 


1. 책 "혼자 공부하는 컴퓨터 구조+운영체제"
2. 유튜브 "혼자 공부하는 컴퓨터 구조 + 운영체제"

반응형

'OS' 카테고리의 다른 글

동기/비동기  (0) 2024.08.10
파일 시스템  (0) 2024.07.28
교착상태(Deadlock)  (0) 2024.07.19
프로세스 동기화  (0) 2024.07.19
CPU 스케쥴링  (0) 2024.07.16
반응형

본 글은 책 "혼자 공부하는 컴퓨터 구조+운영체제" 의 Chapter 13. 교착상태 부분을 읽고 정리한 내용입니다.

 

교착 상태(Deadlock)란?

  • 일어나지 않을 사건을 기다리며 진행이 멈춰버리는 현상

게임 프로세스는 자원 A를 점유한 채 웹 브라우저 프로세스가 점유하고 있는 자원 B의 사용이 끝나길 기다리고, 웹 브라우저 프로세스는 자원 B를 점유한 채 게임 프로세스의 자원 A 사용이 끝나길 기다리는 상황

 

교착 상태는 아주 다양한 상황에서 발생하고 뮤텍스 락에서도 발생할 수 있음

lock1 = true;
while (lock2 == true); # wait
//임계 구역 진입
lock1 = false;
lock2 = true;
while (lock1 == true); # wait
//임계 구역 진입
lock2 = false;
  • 위 두 코드 모두 while 문에서 교착 상태가 발생 
  • 교착 상태를 해결하기 위해서는
    • 발생한 상황을 정확히 표현하고
    • 일어나는 근본적인 이유에 대해서 알아야 함

 

 

자원 할당 그래프(Resource-allocation graph)

  • 어떤 프로세스가 어떤 자원을 사용하고 있고, 어떤 프로세스가 어떤 자원을 기다리는지 표현하는 간단한 그래프


1. 프로세스는 원으로, 자원의 종류는 사각형으로 표현

 

2. 사용할 수 있는 자원의 개수는 자원 사각형 내에 점으로 표현

 

3. 프로세스가 어떤 자원을 할당받아 사용 중이라면 자원에서 프로세스를 향해 화살표를 표시

 

4. 프로세스가 어떤 자원을 기다리고 있다면 프로세스→자원 방향으로 화살표를 표시

프로세스 D가 CPU 할당을 기다리고 있는 상황

 

교착 상태가 발생한 상황은 자원 할당 그래프가 원의 형태를 띄고 있음

 

교착 상태 발생 조건

상호 배제

  • 한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없는 상태

점유와 대기

  • 자원을 할당 받은 상태에서 다른 자원을 할당받기를 기다리는 상태

비선점

  • 프로세스가 자원을 비선점하고 있기 때문

원형 대기

  • 프로세스가 요청 및 할당 받은 자원이 원의 형태를 이루었기 때문 (circular wait)

 

교착 상태 해결 방법

교착 상태 예방

  • 교착 상태 발생 필요 조건 4가지 중 하나를 충족하지 못하게 하는 방법
    • 상호 배제
    • 점유와 대기
    • 비선점
    • 원형 대기

 

자원의 상호 배제 없애기

  • 모든 자원을 공유 가능하게 만듦
  • 현실가능한 방법은 아님

점유와 대기 없애기

  • 특정 프로세스에 자원을 모두 할당하거나 아예 할당하지 않는 방식으로 배분 → 자원의 활용도를 낮출 수 있는 방식임
  • 많은 자원을 필요로 하는 프로세스가 무한정 기다리게 되는 기아현상을 야기할 수 있음

비선점 조건 없애기

  • 선점이 가능한 자원(ex) CPU)에 한해 효과적이지만 모든 자원이 선점 가능한 것은 아님 (ex) 프린터)

원형 대기 조건 없애기

  • 모든 자원에 번호를 붙이고 오름차순으로 자원을 할당

5번 포크를 든 철학자가 다음에 1번 포크를 들 수 없음

  • 하지만 모든 자원에 번호를 붙이고, 어떤 자원에 어떤 번호를 붙이냐에 따라 활용률이 달라짐

 

교착 상태 회피

  • 교착 상태가 발생하지 않을 정도로만 조심히 자원을 할당하는 방식

교착 상태를 회피하는 방법을 학습하기 위해 아래 용어를 알아야 함

안전 순서열(Safe sequence)

  • 교착 상태 없이 안전하게 프로세스들에 자원을 할당할 수 있는 순서를 의미

안전 상태(Safe state)

  • 안전 순서열대로 프로세스들에 자원을 배분하여 교착 상태가 발생하지 않는 상태

불안전 상태(Unsafe state)

  • 안전 순서열이 없는 상황으로 교착 상태가 발생할 수 있는 위험이 있는 상태

예시

  • 컴퓨터 시스템에 총 12개의 자원이 존재
  • 프로세스 P1, P2, P가 실행중
  • 각각 5개, 2개, 2개의 자원을 할당받아 사용중
  • 운영체제가 프로세스에 배분할 수 있는 자원은 3개 (12-5-2-2) 가 남은 상황
  • P1, P2, P3는 각각 10, 4, 9개의 자원을 요구할 수 있음
프로세스 요구량 현재사용량
P1 10 5
P2 4 2
P3 9 2
  • 할당 가능 자원: 12개
  • 할당한 자원: 9개
  • 남은 자원: 3개

 

위의 경우 안전 순서열이 존재: P2→P1→P3

Q. 안전 순서열은 어떻게 알 수 있나? → 은행원 알고리즘 참고

안전 순서열이 존재하지 않는 경우

  • 위의 예시에서 모든 프로세스가 최대의 자원을 요구하는 상황에 P3에 선뜻 하나의 자원을 내줌
프로세스 요구량 현재사용량
P1 10 5
P2 4 2
P3 9 2->3
  • 할당 가능 자원: 12개
  • 할당한 자원: 10개
  • 남은 자원: 2개

위의 상황에서 남은 자원을 P2에 모두 주면, 남은 자원은 0개

프로세스 요구량 현재사용량
P1 10 5
P2 4 4
P3 9 3
  • 할당 가능 자원: 12개
  • 할당한 자원: 12개
  • 남은 자원: 0개

 

위의 예에서 P2가 모든 자원을 반납해도 P1, P3의 요구량을 모두 채울 수 없으므로 서로가 보유하고 있는 자원만을 바라보며 무한정 기다릴 수 밖에 없음 → 불안전 상태로 교착 상태 발생

교착 상태 검출 후 회복

  • 교착 상태가 검출되면
    • 선점을 통한 회복
    • 프로세스 강제 종료를 통한 회복

선점을 통한 회복

  • 교착 상태가 해결될 때까지 한 프로세스씩 자원을 몰아주는 방식

프로세스 강제 종료를 통한 회복

  • 교착 상태에 놓인 프로세스가 모두 강제 종료(→ 작업 내용을 잃음)
  • 교착 상태가 해결될 때까지 한 프로세스씩 강제 종료(→오버헤드가 있지만 잃는 작업 내용 최소화)

 

참고

 


1. 책 "혼자 공부하는 컴퓨터 구조+운영체제"
2. 유튜브 "혼자 공부하는 컴퓨터 구조 + 운영체제"

 
반응형

'OS' 카테고리의 다른 글

파일 시스템  (0) 2024.07.28
가상 메모리(Virtual memory)  (0) 2024.07.28
프로세스 동기화  (0) 2024.07.19
CPU 스케쥴링  (0) 2024.07.16
프로세스와 스레드  (0) 2024.07.14
반응형

본 글은 책 "혼자 공부하는 컴퓨터 구조+운영체제" 의 Chapter 12. 프로세스 동기화 부분을 읽고 정리한 내용입니다.

 

 

동기화의 의미

  • 동시다발적으로 실행되는 많은 프로세스는 서로 데이터를 주고 받으며 협력하며 실행될 수 있고 이 때 데이터의 일관성을 유지해야 함
  • 프로세스 동기화란 프로세스 사이의 수행 시기를 맞추는 것을 의미하고 아래 2가지를 위헌 동기화가 있음
    • 실행 순서 제어: 프로세스를 올바른 순서대로 실행하기
    • 상호 배제: 동시에 접근해서는 안되는 자원에 하나의 프로세스만 접근하게 하기

 

실행 순서 제어를 위한 동기화

  • book.txt 파일에 2가지 프로세스가 동시에 실행중이라고 가정해보자
    • Writer process
    • Reader process
  • 둘은 무작정 아무 순서대로 실행되어서는 안되고 Writer 실행이 끝난 후 Reader가 실행되어야 함

 

상호 배제를 위한 동기화

  • 공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘

 

예시 (Bank account problem)
  • 계좌에 10만원이 저축되어 있다고 가정
  • 프로세스 A는 2만원 입금
  • 프로세스 B는 5만원 입금

프로세스 A 실행되는 과정

  1. 계좌의 잔액 읽음
  2. 읽어들인 잔액에 2만원 더함
  3. 더한 값 저장

프로세스 B 실행되는 과정

  1. 계좌의 잔액 읽음
  2. 읽어들인 잔액에 5만원 더함
  3. 더한 값 저장

이때 두 프로세스가 동시에 실행되었다고 가정했을 때 동기화가 제대로 이루어지지 않은 경우 아래와 같이 전혀 엉뚱한 결과가 나올 수 있음

프로세스 A가 끝나지 않은 상황에서 프로세스 B가 시작됨

정상적으로 작동하길 기대되는 예시

한 프로세스가 진행중이면 다른 프로세스는 기다려야 제대로된 결과를 얻을 수 있는 예

 

생산자와 소비자 문제

  • 생산자와 소비자는 ‘총합’이라는 데이터를 공유
  • 생산자는 총합에 1을 더하고, 소비자는 총합에 1을 뺌

 

  • 생산자와 소비자를 동시에 실행했을 때 예상되는건 총합의 값은 초기 상태를 유지하는 것
  • 하지만 직접 코드를 돌려보면 예상치 못한 결과 발생
#include <iostream>
#include <queue>
#include <thread>

void produce();
void consume();

int sum = 0;

int main() {

    std::cout << "초기 합계: " <<  sum << std::endl;
    std::thread producer(produce);
    std::thread consumer(consume);

    producer.join();
    consumer.join();
    
    std::cout << "producer, consumer 스레드 실행 이후 합계: " <<  sum << std::endl;
    
    return 0;
}

void produce() {
    for(int i = 0; i < 100000; i++) {
        sum++;
    }
}

void consume() {
    for(int i = 0; i < 100000; i++) {
        sum--;
    }
}

초기 합계 : 10
producer, consumer 스레드 실행 이후 합계: -13750

  • 이는 생산자 프로세스와 소비자 프로세스가 제대로 동기화되지 않았기 때문
    • ‘총합’ 데이터를 동시에 사용하는데 소비자가 생산자의 작업이 끝나기 전에 총합을 수정했고, 생산자가 소비자의 작업이 끝나기 전에 총합을 수정했기 때문

 

공유 자원과 임계 구역

  • shared resource: 여러 프로세스 혹은 쓰레드가 공유하는 자원
    • 전역 변수, 파일, 입출력 장치, 보조기억장치
  • 임계구역: 동시에 실행하면 문제가 발생하는 자원에 접근하는 코드 영역
  • 두 개 이상의 프로세스가 임계 구역에 진입하고자 하면 둘 중 하나는 대기해야 함

 

Process A가 임계 구역에 진입하면, Process B는 대기해야 함

 

Race condition

  • 임계 구역은 두 개 이상의 프로세스가 동시에 실행되면 안되는 영역이지만 여러 프로세스가 동시에 다발적으로 실행하여 자원의 일관성이 깨지는 경우

Race condition의 근본적인 이유

  • 고급언어(C/C++, Python) → 저급언어로 변환되며 코드가 늘어날 수 있음
  • 이 때 context switching이 발생하면 예상치 못한 결과를 얻을 수 있음

 

 

상호 배제를 위한 동기화는 이런 일이 발생하지 않도록 두 개 이상의 프로세스가 임계 구역에 동시에 접근하지 못하도록 관리하는 것을 의미하며 운영체제는 3가지 원칙하에 해결

  1. progress: 임계 구역에 어떤 프로세스도 진입하지 않았다면 임계 구역에 진입하고자 하는 프로세스는 들어갈 수 있어야 함
  2. Mutual exclusion : 한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 임게 구역에 들어올 수 없음
  3. bounded waiting: 한 프로세스가 임계 구역에 진입하고 싶다면 그 프로세스는 언젠가는 임게 구역에 들어올 수 있어야 함 (무한정 대기 X)

 

동기화 기법

동기화를 위한 대표적인 도구 3가지

  1. 뮤텍스 락
  2. 세마포
  3. 모니터

 

뮤텍스 락(Mutex lock)

  • Mutual EXclusion lock, 상호 배제를 위한 동기화 도구로 기능을 코드로 구현한 것
  • 매우 단순한 형태는 하나의 전역 변수와 두개의 함수
    • 자물쇠 역할: 프로세스들이 공유하는 전역 변수 lock
    • 임계구역을 잠그는 역할: acquire 함수
    • 임계 구역의 잠금을 해제하는 역할: release 함수

 

acquire 함수

  • 프로세스가 임계 구역에 진입하기 전에 호출하는 함수
  • 임계 구역이 잠겨있으면 열릴 때까지(lock이 false가 될 때까지) 임계 구역을 반복적으로 확인
  • 임계 구역이 열려있으면 임계 구역을 잠그는 함수

release 함수

  • 임계 구역에서의 작업이 끝나고 호출하는 함수
acquire(){
    while (lock ==true) # 반복해서 확인하는 대기 방식을 busy wait이라고 함
        ;               # 임계 구역이 잠겨 있는지 반복적으로 확인
    lock = true;        # 만약 임계 구역이 잠겨 있지 않다면 임계 구역 잠금
}

release() {
    lock = false; # 임계 구역 작업이 끝나서 잠금 해제
}

 

acquire();
// 임계구역 (ex) '총합' 변수 접근)
release();

 

 

세마포(Semaphore)

  • 사전적 의미: 수기 신호

 

  • 뮤텍스 락과 비슷하지만 좀 더 일반화된 방식의 동기화 도구
  • 공유 자원이 여러개 있는 상황에서도 적용이 가능한 동기화 도구

 

  • 단순한 형태로 하나의 변수와 두개의 함수로 구현가능
    • 임계 구역에 진입할 수 있는 프로세스의 개수를 나타내는 전역 변수 S
    • 임계 구역에 들어가도 좋은지 기다려야 할지를 아려주는 wait 함수
    • 이제 가도 좋다는 신호를 주는 signal 함수
wait()
{
    while( S <= 0) # 임계 구역에 진입할 수 있는 프로세스가 0개 이하라면
    ;              # 사용할 수 있는 자원이 있는지 반복적으로 확인하고
    S--;           # 진입할 수 있는 프로세스 개수가 1개 이상이면 S를 1 감소시키고 진입
}

signal()
{
    S++;           # 임계 구역에서의 작업을 마친 뒤 S를 1 증가 시킴
}
wait()
// 임계 구역
signal()

 

예시

세 개의 프로세스 P1, P2, P3가 2개의 공유 자원(S=2)에 순서대로 접근한다고 가정하면,

  1. 프로세스 P1 wait 호출, S는 2→1로 감소
  2. 프로세스 P2 wait 호출, S는 1→0으로 감소
  3. 프로세스 P3 wait 호출, S는 현재 0이므로 무한히 반복하며 S확인
  4. 프로세스 P1 임계 구역 작업 종료, signal 호출, S는 0→1
  5. 프로세스 P3에서 S가 1이 됨을 확인하고 S 1→0 만들고 임계 구역 진입

 

위의 3 과정에서 busy wait 반복하며 확인하며 CPU 사이클이 낭비됨
* busy wait: 쉴새없이 반복하며 확인해보며 기다리는 과정

해결 방법

  1. 사용할 수 있는 자원이 없을 경우 대기 상태로 만듦 (해당 프로세스의 PCB를 waiting queue에 삽입)
  2. 사용할 수 있는 자원이 생겼을 경우 대기 큐의 프로세스를 준비 상태로 만듦 (해당 프로세스의 PCB를 waiting queue → ready queue 로 이동)
wait()
{
    S--;
    if ( S < 0) {
        add this process to waiting queue;
        sleep();
	}
}

signal()
{
    S++;
    if (S<=0) 
    # remove a process p from waiting Queue;
    wakeup(p); # waiting queue -> ready queue
  }
}

프로세스 4개이고, 공유 자원이 2개라고 가정해보면,

  1. 프로세스 P1 wait 호출, S는 2→1로 감소
  2. 프로세스 P2 wait 호출, S는 1→0으로 감소
  3. 프로세스 P3 wait 호출, S는 0→-1이 되고 waiting queue로 이동
  4. 프로세스 P4 wait 호출, S는 -1→-2가 되고 waiting queue로 이동
  5. 프로세스 P1 임계 구역 작업 종료, signal 호출, S는 -2→-1이 되고 PCB를 waiting queue → ready queue로 이동
  6. 프로세스 P2 임계 구역 작업 종료, signal 호출, S는 -1→0이 되고, PCB를 waiting queue → ready queue로 이동

 

세마포는 프로세스의 실행순서 동기화도 지원

  • 변수 S를 0으로 두고 먼저 실행할 프로세스 뒤에 signal 함수, 다음에 실행할 프로세스 앞에 wait함수를 붙이면 됨
P1 P2
  wait()
// 임계 구역 // 임계 구역
signal()  
  • 위의 경우 프로세스의 실행 순서에 상곤없이 P1→P2 순으로 임계 구역에 진입

 

모니터(Monitor)

  • 세마포는 훌륭한 프로세스 동기화 도구지만 매번 임계 구역 앞뒤로 wait & signal 함수를 명시해야 함
  • 모니터는 사용자(개발자)가 다루기에 편한 동기화 도구

상호 배제를 위한 동기화

  • 공유자원과 공유 자원에 접근하기 위한 인터페이스를 묶어서 관리
  • 프로세스는 반드시 인터페이스를 통해서만 공유 자원에 접근하도록 함

공유자원에는 하나의 프로세스만 접근

 

실행 순서 제어를 위한 동기화

  • 내부적으로 조건 변수(condition variable)를 이용
  • 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수

 

조건 변수별 queue가 있고 이를 통해 실행 순서를 결정할 수 있음

  • 조건 변수로 wait과 signal 연산을 수행할 수 있음
    • 조건변수.wait(): 대기 상태로 변경, 조건 변수에 대한 큐에 삽입

 

  • 조건변수.signal(): wait()으로 대기 상태로 접어든 조건 변수를 실행상태로 변경

 

모니터 안에는 하나의 프로세스만 있을 수 있음

  • wait()을 호출했던 프로세스는 signal()을 호출한 프로세스가 모니터를 떠난 뒤에 수행을 재개
  • signal()을 호출한 프로세스의 실행을 일시 중단하고 자신이 실행된 뒤 다시 signal()을 호출한 프로세스의 수행을 재개

 

참고

 


1. 책 "혼자 공부하는 컴퓨터 구조+운영체제"
2. 유튜브 "혼자 공부하는 컴퓨터 구조 + 운영체제"

반응형

'OS' 카테고리의 다른 글

가상 메모리(Virtual memory)  (0) 2024.07.28
교착상태(Deadlock)  (0) 2024.07.19
CPU 스케쥴링  (0) 2024.07.16
프로세스와 스레드  (0) 2024.07.14
운영체제를 공부해야하는 이유와 커널  (0) 2024.07.14

+ Recent posts