혼공컴운

[혼공컴운] 10장. 프로세스와 스레드

게으른 the lazy 2024. 7. 29. 02:18

https://www.youtube.com/watch?app=desktop&v=4rLW7zg21gI

10. 프로세스와 스레드

  • 본격적으로 OS를 알아본다.
  • 일단 파일이었던 프로그램이 돌아가는 프로그램이 된 프로세스를 알아야 한다.
  • 그리고 프로세스는 여러 개가 돌아갈 수 있다.
  • 어떻게? 스레드도 알아보자.

10.1 프로세스 개요

  • 지난 장에서 얘기했듯이, 보조기억장치에 있는 것은 파일일 뿐이다.
  • 파일은 그 자체로 실행 중인 무언가가 아니다.
  • 실행 상태가 되려면 메모리에 올라가서 정보의 흐름을 타야 한다.
  • 작업 관리자의 프로세스 탭에 나오는 것들이 바로 이것이다.
  • 윈도우 10 기준, 프로세스는 앱과 백그라운드 프로세스로 분리된다.
  • 앱은 사용자에게 보이는 프로세스, 백그라운드는 안 보이는 프로세스다.

10.1.1 프로세스 제어 블록

  • CPU는 바쁘다! 모든 프로세스를 동시에 실행할 수 없다.
  • 따라서 줄을 서서 기다려야 한다.
  • OS가 이 줄을 관리하는데, 관리하려면 장부가 필요하다.
  • 그래서 프로세스한테 식별표를 붙였다!
  • 이 식별표를 프로세스 제어 블록(PCB; Process Control Block)이라고 부른다.
  • 당연히 PCB는 메모리의 커널 영역에 생성된다.
  • PCB는 프로세스 생성 시 만들어지고, 종료 시 폐기된다.
  • 아래는 PCB에 들어있는 정보들이다.
    • 프로세스 ID: 식별 번호이다. 당연히 겹치면 안된다.
    • 레지스터 값: 프로세스 실행에 사용한 레지스터 값들이다. CPU는 바쁘므로 프로세스가 들어왔다고 한 번에 끝내지 못한다. 작업하던 레지스터 값들을 중간 저장 해야 한다.
    • 프로세스 상태: 실행 중인지, 대기 중인제 등등의 상태이다.
    • CPU 스케쥴링: 언제 CPU님을 뵐 수 있는지에 대한 정보이다.
    • 메모리 관리 정보: 프로세스가 메모리 어디에 저장되어 있는지를 저장한다.

10.1.2 문맥 교환

  • 운영체제 공부하는데 갑자기 문맥이 웬말?
  • 스타크래프트 선수에 비유해보자.
  • 본인 일꾼 관리를 하는데 갑자기 공격 당하고 있다는 알림(인터럽트)이 떴다.
  • 얼른 해당 위치로 이동해서 방어를 해야 한다.
  • 이때 일꾼 관리하던 내용을 기억하고 있어야 한다.
  • 그래야 방어 완료 후 다시 본진으로 와서 일꾼 관리를 마저 할 수 있다.
  • 프로세스는 수시로 CPU를 영접했다가 물러난다.
  • 그럴 때마다 작업하던 정보를 잘 저장해야 한다.
  • 프로세스가 작업을 재개하기 위해 기억해야 할 정보를 문맥(context)이라고 부른다.
  • 예를 들어 프로세스 A가 실행되던 도중 프로세스 B가 끼어들었다면?
  • 프로세스 A의 문맥을 PCB에 저장하고, 프로세스 B의 문맥을 PCB에서 가져온다.
  • 프로세스 B가 볼 일을 다 보면 다시 B의 문맥을 저장하고 A의 문맥을 가져온다.
  • 이것을 문맥 교환(context switching)이라고 부른다.

출처: https://byjus.com/gate/context-switching-in-os-notes/

  • 다만 이 과정은 엄청 빠르게 일어나므로, 우리 눈에는 CPU가 여러 일을 동시에 처리하는 것처럼 보인다.

10.1.3 프로세스의 메모리 영역

  • 메모리는 커널 영역과 사용자 영역으로 나눈다고 지난 장에서 말한 바 있다.
  • 커널 영역은 사용자가 감히 건드릴 수 없는 영역이다.
  • 사용자 영역은 또 여러 영역으로 분할된다.
  • 코드 영역, 데이터 영역, 힙 영역, 스택 영역이 있다.

  • 코드 영역
    • 텍스트 영역이라고 부르기도 한다.
    • 실행할 코드, 즉 기계어 명령어가 저장된다.
    • 여긴 우리가 함부로 건드리면 안되므로 읽기 전용이다.
    • 크기가 변하지 않는다. 프로그램을 구성하는 명령어들이 바뀌지 않기 때문이다.
    • 그래서 정적 할당 영역이라고 부른다.
  • 데이터 영역
    • 프로그램 실행 동안 유지할 데이터가 저장되는 공간이다.
    • 전역 변수를 떠올리면 된다.
    • 코드 영역과 마찬가지로 정적 할당 영역이다.
  • 힙 영역
    • 프로그래머가 직접 할당할 수 있는 저장 공간이다.
    • 메모리는 OS 소유이고 우리는 빌려 쓸 뿐이다.
    • 썼으면 돌려줘야 한다.
    • 안 그러면 OS한테 혼난다...가 아니고 OS가 기절(?)한다.
  • 스택 영역
    • 데이터를 일시적으로 저장하는 공간이다.
    • 지역 변수, 함수의 매개 변수 등이 여기에 저장된다.
    • 힙과 스택을 동적 할당 영역이라고 부른다.

  • 동적 할당 영역의 데이터는 수명을 다 하면 없어지고 공간은 OS에 반환된다.
  • 이 영역은 실시간을 크기고 바뀔 수 있으므로 겹치지 않는 것이 좋다.
  • 그래서 힙 영역은 낮은 주소에서 높은 쪽으로, 스택 영역은 높은 주소에서 낮은 쪽으로 쌓인다.

출처: https://courses.grainger.illinois.edu/cs225/fa2022/resources/stack-heap/


10.2 프로세스 상태와 계층 구조

  • 작업 관리자에는 세부 정보 탭이 있다.
  • 여기를 보면 내 PC에서 돌아가는 모든 프로세스들의 세부 정보를 볼 수 있다.
  • 상태 컬럼이 있는데, 실행 중도 있고, 일시 중단됨도 있다.
  • 이것이 프로세스 상태이다.
  • 프로세스가 가질 수 있는 상태들을 간단히 요약해본다.

  • 생성 상태(new)
    • 생성 중인 상태이다.
    • 이제 막 메모리에 적재되었고 PCB를 받았다.
    • 아직 실행할 수 없다. 왜냐면...
  • 준비 상태(ready)
    • 준비가 되어야 대기줄에 들어갈 수 있기 때문이다.
    • 본인 차례를 기다리는 중이다.
    • 그리고 드디어...
  • 실행 상태(running)
    • CPU님을 영접하여 실행되고 있다.
    • CPU님은 바쁘므로 할당된 시간 동안만 만날 수 있다.
    • 시간을 모두 쓰면(타이머 인터럽트 발생) 다시 준비 상태가 된다.
  • 대기 상태(blocked)
    • 프로세스가 입출력장치를 사용해야 할 때가 있다.
    • 입출력장치는 느리다! 답답하다!
    • 입출력 작업을 요청한 프로세스는 입출력 장치로부터 입출력 완료 인터럽트를 받을 때까지 기다려야 한다.
    • 이 상태가 대기 상태이다.
  • 종료 상태(terminated)
    • 본인의 소명을 다 한 프로세스는 PCB를 반납하고 생을 마친다.
    • 괜히 슬프다.
  • 참고로 suspended도 있는데, 메모리를 할당받지 못한 상태라고 한다.

출처: https://www.researchgate.net/figure/Process-State-Diagram_fig1_260973132


10.2.1 프로세스 계층 구조

  • 프로세스는 실행 도중 시스템 호출을 통해 다른 프로세스를 생성할 수 있다.
    • 무슨 다단계도 아니고...
  • 컴퓨터가 켜지면 최초의 프로세스가 생성되는데, 이 프로세스는 OS마다 다르다.
  • 최초의 프로세스를 제외한 모든 프로세스는 부모 프로세스를 갖는다.
  • 책에는 bash, Vim 등이 언급되는데, 윈도우 예시도 있으면 좋겠다.
  • 이 부분은 구체적인 예시가 없어서 좀 이해가 어렵다.

출처: https://velog.io/@mmodestaa/혼자-공부하는-컴퓨터-구조-운영체제-Section-10.-프로세스-개요

  • 부모와 자식은 다르므로, 둘의 PID도 다르다. 자식은 부모의 PID인 PPID(Parent PID)를 갖는다.
    • PPAP가 생각난다. 아, 파인애플 먹고 싶다. (사과는 아까 먹었다.)
  • 프로세스를 관리하는 시스템 호출은 3가지가 있다.
    • fork: 자식 프로세스를 생성한다.
    • exit: 현재 프로세스를 종료한다.
    • wait: 부모가 자식의 종료를 기다리고 확인한다.

10.2.2 확인 문제

  • 다음의 프로세스 상태 다이어그램에서 빈 칸을 채우시오.

  • 1번: 이제 막 생성되었으므로 생성 상태(new)
  • 2번: CPU님을 영접하고 싶은 준비 상태(ready)
  • 3번: 드디어 실행되고 있어서 기쁜 실행 상태(running)
  • 4번: 이제 여한이 없는 종료 상태(terminated)
  • 5번: 아 ㅡㅡ 저 느려터진 프린터가 발목잡는 대기 상태(blocked)

10.3 스레드

  • 프로세스는 한 번에 여러 작업을 동시에 처리할 수 있다.
  • 웹 브라우저는 사용자 입력도 받아야 하고, 검색도 해야 하고, 화면 출력도 해야 한다.
  • 어떻게 가능할까?

  • 스레드의 정의는 "프로세스를 구성하는 실행 단위"이다.
  • 예전에는 이 단위가 1개였으므로 싱글 스레드였다. 사실 스레드라는 개념이 무의미하다.
  • 요즘은 멀티스레드로 돌아간다.
  • 아니, 그래서, 스레드가 뭐지?

  • 스레드의 구성 요소를 알아보면 도움이 될 것이다.
  • 스레드마다 하는 일이 다르므로 식별을 위한 ID가 필요하다.
  • 하는 일이 다르므로 레지스터 값도 다를 것이다. 그 외에 스택, 프로그램 카운터도 다르다.
  • 이제 전부다! 나머지는? 서로 공유한다.
    • PCB, 코드, 데이터, 힙, 파일 등을 모두 공유한다.

출처: https://velog.io/@mmodestaa/혼자-공부하는-컴퓨터-구조-운영체제-Section-10.-프로세스-개요

  • 좁은 영역에서 각자 할 일 하는 움파룸파를 떠올리면 될 것 같다.

출처: https://www.abc.net.au/news/2023-12-13/deep-roy-on-wonka-oompa-loompas/103213304


  • 다만 멀티 스레드는 단점도 있다.
  • 스레드 하나에서 문제가 생기면 다른 스레드도 영향을 받는다.