Post

Process & Thread

쉽게배우는 운영체제

Process

프로그램이 실행된다는 것은 해당 코드가 메모리에 올라와서 작업이 진행된다는 의미이다. 프로그램은 저장장치에 저장되어 잇는 정적인 상태이고, 프로세스는 실행을 위해 메모리에 올라온 동적인 상태이다.

  • 프로그램 → 프로세스
    • 프로그램을 실행 시킬 때 운영체제는 프로그램을 메모리로 가져오고 그와 동시에 작업 지시서에 해당하는 PCB(프로세스 제어 블록)을 만든다.
    • 즉, 프로그램이 프로세스가 되었다는 것은 PCB를 받았다는 것
  • PCB 구성요소 중 대표적인 3가지
    • 프로세스 구분자(PID) : 메모리에는 여러 개의 프로세스가 존재하고 이들을 구분하는 구분자(ID)가 있다
    • 메모리 관련 정보 : CPU가 실행하려는 프로세스가 메모리 어디에 저장 되어 있는지 알기 위한 메모리 위치정보와 보호를 위한 경계 레지스터, 한계 레지스터 값 등
    • 각종 중간값 : 시분할 시스템에서는 여러 프로세스가 번갈아 실행되기 때문에, 다음에 작업해야 할 코드의 위치가 담긴 레지스터인 프로그램 카운터가 저장되고 작업의 중간값을 보관 중인 다른 레지스터도 함께 저장된다.

PCB는 운영체제가 해당 프로세스를 위해 관리하는 데이터 구조이기 때문에 운영체제 영역에 만들어지고, 프로세스가 종료되면 메모리에서 프로세스와 함께 삭제된다.

프로세스 상태

  • 생성 상태
    • 프로세스가 메모리에 올라오고 운영체제로부터 PCB를 할당 받은 상태
    • 생성된 프로세스는 PCB와 함께 준비 상태로 옮겨짐
  • 준비 상태
    • 생성된 프로세스가 CPU를 얻을 때 까지 기다리는 상태
    • 준비 상태에 있는 프로세스 중 다음에 실행할 프로세스는 CPU 스케쥴러가 정해주고, CPU 스케줄러는 맨 앞에 있는 PCB를 CPU에게 전달하여 작업이 이어지게 한다.
    • 이렇게 준비 상태의 프로세스 중 하나를 실행 상태로 바꾸는 CPU 스케줄러의 작업을 dispatch 라고 한다.
  • 실행 상태
    • 준비 상태의 프로세스들 중 하나가 CPU를 얻어 실제 작업을 수행하는 상태
    • 실행 상태가 된 프로세스는 일정 시간 동안 CPU를 사용할 권리를 얻는다. 주어진 시간을 다 사용하고도 작업을 끝내지 못하면 준비 상태로 돌아와 다음 차례를 기다린다.
    • CPU를 사용할 권리를 얻은 시간을 타임 퀸텀, 타임 슬라이스 라고 부름
  • 완료 상태
    • 실행 상태의 프로세스가 주어진 시간 동안에 작업을 완료한 상태
  • 대기 상태
    • 입출력관리자에게 입출력을 요구한 프로세스가 입출력이 완료될 때 까지 기다리는 상태, 효율성을 높이기 위해 입출력 요청 후 기다리는 중인 프로세스를 실행 상태로 두지 않음
    • 대기 상태의 프로세스는 요청한 입출력이 완료되면 입출력 관리자로부터 인터럽트를 받고, 바로 실행 상태로 가는게 아니라 준비 상태로 돌아가 자기 차례를 기다림

| 상태 | 설명 | 작업 | | — | — | — | | 생성 상태 | 프로그램을 메모리에 가져와 실행 준비가 완료된 상태 | 메모리 할당, PCB 생성 | | 준비 상태 | 실행을 기다리는 프로세스 중 CPU 스케줄러가 선택 | dispatch(PID): 준비 → 실행 | | 실행 상태 | 선택된 프로세스가 타임 퀸텀을 얻어 CPU를 사용하는 상태 | timeout : 실행 → 준비 exit : 실행 → 완료 block : 실행 → 대기 | | 대기 상태 | 실행 상태의 프로세스가 입출력을 요구하고 완료를 기다리는 상태, 입출력이 완료되면 준비 상태가 된다 | wakeup : 대기 → 준비 | | 완료 상태 | 프로세스가 종료된 상태, 사용하던 모든 데이터가 정리됨 | 메모리, PCB 삭제 |

프로세스 구조

  • 코드영역
    • 프로그램의 본문이 기술된 곳으로, 프로그래머가 작성한 프로그램은 코드영역에 탑재되며 탑재된 코드는 읽기 전용으로 처리 된다
  • 데이터영역
    • 코드가 실행되면서 사용하는 변수,파일 등의 각종 데이터를 모아두는 곳이다. 데이터는 변하는 값이기 때문에 이 영역은 읽기/쓰기 가능
  • 스택 영역
    • 운영체제가 프로세스를 실행하기 위해 사용하는 부수적인 데이터를 모아두는 곳. 예를들어 함수를 호출하면 함수를 수행하고 원래 프로그램으로 되돌아갈 위치를 이 영역에 저장한다.

예를들어 엑셀을 실행하면, 이 프로그램은 코드 영역에 탑재되고 엑셀로 편집 중인 문서는 데이터 영역에 탑재된다. 또한, 운영체제가 엑셀을 작동하기 위해서 사용하는 각종 부가 데이터는 스택 영역에서 관리한다.

프로세스 생성과 복사

  • fork()
    • 실행 중인 프로세스로 부터 새로운 프로세스를 복사하는 함수
    • 엑셀에서 문서작업을 하다가 새로운 엑셀을 하나 더 실행하면, 새로운 엑셀을 실행하는게 아니라 기존에 사용중이던 엑셀을 복사한다.
    • PCB를 포함한 부모 프로세스의 대부분이 복사되지만 PID,메모리 관련 정보 등은 변경 된다

IPC

원래는 process는 독립된 메모리 공간을 할당 받기 때문에 다른 process의 메모리를 참조할 수는 없으나, 운영체제는 process간의 자원 접근을 위한 IPC(Inter PRocess Commmunication) 제공

공유 메모리(Shared Memory)

공유 메모리 방식에서는 process들이 주소 공간의 일부를 공유하고, 공유한 메모리 영역에 읽기/쓰기를 통해서 통신을 수행한다.

process가 공유 메모리 할당을 kernel에 요청하면 kernel은 해당 process에 메모리 공간을 할당해준다. 공유 메모리 영역이 구축된 이후에는 모든 접근이 일반적인 메모리 접근으로 취급되기 때문에 더이상 kernel의 도움없이도 각 process들이 해당 메모리 영역에 접근할 수 있기 때문에 IPC속도가 빠르다.

하지만 동시에 같은 메모리 위치에 접근하게 되면 일관성 문제가 발생할 수 있기 때문에 세마포어, 뮤텍스 등을 활용해 동기화 문제를 해결해야한다.

  • 세마포어 (Semaphore) : S개의 thread만이 공유 자원에 접근할 수 있도록 제어하는 동기화 기법, 자원에 접근하면 S를 감소시키고 자원 사용이 끝나면 S를 증가시켜 관리함.(S가 0 이면 모든 자원이 사용중임을 의미)
  • 뮤텍스 (Mutex) : 1개의 스레드만이 공유 자원에 접근할 수 있도록 하여, 경쟁 상황(race condition)를 방지하는 기법(lock과 비슷)

커널 (Kernel) : 운영체제의 핵심 부분으로 하드웨어와 소프트웨어간 통신을 관리하고 프로그램 실행, 메모리 관리, 입출력 장치의 관리, 파일 시스템 조작, 네트워킹, 보안 관리 등 다양한 중요한 기능을 담당

메시지 전달 방법(Message Passing)

메시지 전달 방법은 프로세스 간에 데이터를 메시지 형태로 전송하는 방식. 예를 들면, A process가 kernel로 message를 보내면 kernel이 B process에게 message를 보내주는 방식으로 동작

메시지를 전달하고 수신하는데 시간이 소요되기 때문에 메모리 공유보다는 속도가 느리지만, 충돌을 회피할 필요가 없기 때문에 적은양의 데이터를 교환하는 데 유용하고 구현하기가 쉽다. (pipe, socket, message queue 등)

  • Socket
    • 소켓은 네트워크 통신의 endpoint로 IP 주소와 port의 조합을 사용해 특정 서비스나 프로세스를 식별
    • 소켓 통신 단계
      1. 소켓 생성 : 데이터 통신을 위해 프로세스는 TCP/IP or UDP 중 어떤 프로토콜 사용할 지 결정
      2. 바인딩 : 소켓에 특정 IP 주소와 port 할당
      3. 연결 : TCP 기반의 경우 클라이언트가 서버에 연결을 요청하고 서버가 이를 수락하면 연결 수립(UDP는 연결이 필요없는 프로토콜임)

Multi Process

Multi process란 2개 이상의 process가 동시에 실행되는 것으로 동시에라는 말은 동시성(concurrency)과 병렬성(parallelism) 두 가지를 의미한다.

동시성은 CPU core가 1개일 때, 여러 process를 짧은 시간동안 번갈아 가면서 연산을 하게 되는 시분할 시스템(time sharing system)으로 실행되는 것이고 병렬성은 CPU core가 여러개일 때, 각각의 core가 각각의 process를 연산함으로써 process가 동시에 실행되는 것이다.

각 porcess는 각자의 독립적인 memory 영역을 차지하여 동시에 적재되고, 하나의 CPU는 하나의 process만 연산할 수 있다. 각 process가 자신의 memory 영역에만 접근하도록 OS가 관리해준다.

A process가 진행되고 있을 때에는 A process의 code 영역을 PC(Program Counter) 레지스터가 가리키고 있고, B process가 시작되면 B process의 code 영역을 가리키게 된다. 즉, PC 레지스터가 가리키는 곳에 따라 process를 변경해가며 multi process가 진행된다.

Context

하나의 process 가 매우 짧은 시간동안 CPU를 점유하여 작업을 일부 수행하고, 다른 porcess에게 CPU 점유를 넘기게 되는데 이런 시스템을 시분할 시스템이라고 부른다.

이런 시분할 시스템 상에서 어떤 process가 어디까지 작업을 수행했고 레지스터에 어떤 값이 저장되어 있었는지에 대한 정보가 Context이고, Context는 PCB에 저장된다.

PCB

PCB는 운영 체제가 프로세스를 표현한 자료구조로 PCB에는 프로세스의 중요한 정보가 포함되어 있기 때문에, 일반 사용자가 접근하지 못하도록 보호된 메모리 영역 안에 저장된다.

  • 프로세스 제어블록 구성
    • 포인터 : 준비 상태, 대기상태는 Queue로 운영되고, 이를 구현 할 때 포인터를 사용
    • 프로세스 상태 : 현재 프로세스가 어떤 상태인지 나타내고, PCB의 두번째 블록에 저장된다
    • 프로세스 구분자 : PID, 여러 프로세스를 구별하기 위한 구별자
    • 프로그램 카운터 : 다음 실행될 명령어의 위치를 가리키는 프로그램 카운터의 값 저장
    • 프로세스 우선순위 : 다양한 우선순위의 프로세스가 대기 상태로 들어오기 때문에 대기 상태의 큐도 우선순위 별로 따로 운영된다. 즉, 우선순위에 따라 PCB가 여러 줄로 서있다. CPU 스케줄러가 준비 상태에 있는 프로세스를 선택할 때, 프로세스 우선순위를 기준으로 삼는다.
    • 각종 레지스터 정보 : 프로세스가 실행되는 중에 사용하던 레지스터의 값이 저장된다. 이전에 실행할 때 사용한 레지스터의 값을 보관해야 다음에 실행할 수 있기 때문에, 자신이 사용하던 레지스터의 중간값을 보관한다.
    • 메모리 관리 정보 : 프로세스가 메모리의 어디에 있는지 나타내는 메모리 위치정보, 메모리 보호를 위해 사용되는 한계 레지스타 값, 경계레지스터 값 등이 저장된다. 그리고 세그먼테이션 테이블, 페이지 테이블 등의 정보도 보관된다.
    • 할당된 자원 정보 : 프로세스를 실행하기 위해 사용하는 입출력 자원이나 오픈 파일 등에 대한 정보

Context Switching

한 프로세스에서 다른 프로세스로 CPU 제어권을 넘겨주는 것으로, 이 때 이전의 프로세스의 상태를 PCB에 저장하여 보관하고 새로운 프로세스의 PCB를 읽어서 보관된 상태를 복구하는 작업이 수행된다.

  • Context Switching with Multi-Process
    • 각 프로세스는 독립된 메모리 영역(code, data, heap, stack)을 가지고 있기 때문에, context switching을 할 때 CPU 레지스터의 상태 뿐 아니라 메모리 주소 공간 까지 변경해야함
  • Context Switching with Multi-Thread
    • 스레드는 프로세스 내에서 code, data, heap 영역을 공유하기 때문에 메모리 주소의 변경 없이 스레드의 실행 정보(레지스터, stack)만 변경하면됨
    • 멀티프로세스에 비해 context switching이 가볍고 빠르지만, 스레드 간 자원 공유로 인한 동기화 문제 고려해야함

Thread

thread는 한 process 내에서 실행되는 동작(기능 function)의 단위. 각 thread는 속해있는 process의 Stack 메모리를 제외한 나머지 memory 영역을 공유한다.

독립적인 Stack 영역이 필요한 이유는 각 스레드가 자신만의 함수 호출 기록과 지역 변수를 관리해야 하기 때문이다. Stack은 함수 호출과 관련된 정보를 저장하는 데이터 구조로, 함수가 호출될 때마다 해당 함수의 실행 정보(예: 매개변수, 지역 변수, 반환 주소 등)가 스택에 저장되고 함수가 종료되면 해당 정보는 스택에서 제거된다.

thread는 process내에서 독립적인 기능을 수행하는데, 이 뜻은 독립적으로 함수를 호출한다는 것.

  • 프로세스의 작업 과정
    • 운영체제는 코드,데이터를 메모리로 가져오고 PCB 생성 후 작업에 필요한 메모리 영역을 확보하여 준비된 프로세스를 큐에 삽입함
    • 프로세스가 생성되면 CPU 스케줄러는 프로세스가 해야 할 일을 CPU에 전달하고 CPU는 작업 수행하는데, 이 때 CPU스케줄러가 CPU에 전달하는 일 하나가 스레드 이다
    • 운영체제 입장에서 작업 단위는 프로세스, CPU 입장에서 작업 단위는 스레드
    • `즉, 스레드는 프로세스의 코드에 정의된 절차에 따라 CPU에 작업 요청을 하는 실행단위
  • 멀티 스레드
    • 프로세스 내 작업을 여러개의 스레드로 분할해서 작업의 부담을 줄이는 프로세스 운영 기법
  • 멀티 프로세싱
    • CPU 여러 개를 사용해서 여러 개의 스레드를 동시에 처리하는 작업 환경
    • 하나의 컴퓨터에 여러 개의 CPU 혹은 하나의 CPU 내 여러 개의 코어에 스레드를 배정하여 동시에 작동하게 하는 것

Multi thread

Multi thread란 하나의 process가 동시에 여러개의 일을 수행할수 있도록 해주는 것으로, 하나의 process에서(실행이 된 하나의 program에서) 여러 작업을 병렬로 처리하기 위해 multi thread를 사용한다. multi thread에서는 한 process 내에 여러 개의 thread가 있고, 각 thread들은 Stack 메모리를 제외한 나머지 영역(Code, Data, Heap) 영역을 공유한다.

한 process내에서 thread 끼리 context switching가 발생하기 때문에 각 thread 마다 PC 레지스터가 있어야 한다.

  • 멀티 스레드 장점
    • 응답성 향상 : 한 스레드가 입출력 작업 중이더라도, 다른 스레드가 작업을 계속해서 사용자의 작업 요구에 빠르게 대응 가능하다
    • 자원 공유 : 한 프로세스 내에서 스레드를 생성하면, 프로세스가 가진 모든 자원을 스레드가 공유한다
    • 효율성 향상 : 여러 개의 프로세스를 생성하는 것과 달리 멀티 스레드는 불필요한 자원의 낭비를 줄인다
  • 멀티 스레드 단점
    • 모든 스레드가 해당 프로세스의 자원을 공유하기 때문에, 한 스레드에 문제가 생기면 전체 프로세스에 영향을 끼침
    • python에서는 이런 동기화 문제를 Lock, Semaphore, Queue, Event 등으로 관리함

Multi-Process vs Multi-Thread

  • Multi-Process
    • 장점 -안정성: 하나의 프로세스는 독립된 메모리 공간을 가지기 때문에 어떤 프로세스가 실패해도 다른 프로세스에 영향이 없다. -자원의 독립성: 각 프로세스는 독립된 메모리 공간을 가지므로, 프로세스 간 자원의 충돌 위험이 적다. -단점 -오버헤드: 프로세스 간 컨텍스트 스위칭이 비교적 무겁고, 비용이 많이듬 -통신 비용: IPC(프로세스간 통신)이 복잡
    • 자원의 격리가 필요한 경우 / 안정성, 보안이 중요한 앱 / CPU 사용량이 높은 작업의 병렬처리에 유용
  • Multi-Thread
    • 장점
      • 자원의 효율성: 모든 스레드가 같은 프로세스의 메모리를 공유하기 때문에, 메모리 사용량이 감소
      • 응답성: 하나의 스레드가 블록되어도 다른 스레드가 계속 작업을 수행할 수 있어, 프로그램의 전체 응답성 향상
    • 단점
      • 동기화 문제: 스레드 간 자원 공유로 인해 데이터 일관성과 동기화 문제가 발생(python에서는 이런 동기화 문제를 Lock, Semaphore, Queue, Event 등으로 관리)
      • 안정성 문제: 하나의 스레드에서 발생한 문제가 전체 프로세스에 영향끼침. 즉, 하나의 스레드에서 치명적인 예외가 발생하면 전체 프로세스가 종료될 수 있습니다.
    • 자원 공유가 필요한 경우(웹 서버, 캐시) / 파일 다운로드와 같이 백그라운드 작업
This post is licensed under CC BY 4.0 by the author.

© . Some rights reserved.

Using the Chirpy theme for Jekyll.