GitHub

https://github.com/Choidongjun0830

CS

3.3 프로세스와 쓰레드

gogi masidda 2024. 9. 17. 23:03

'면접을 위한 CS 전공지식 노트' 책을 보며 공부한 내용입니다.

 

프로세스는 컴퓨터에서 실행되고 있는 프로그램을 말한다. CPU 스케줄링의 대상이 되는 작업이라는 용어와 같은 의미로 쓰인다.

쓰레드는 프로세스와 내 작업의 흐름을 말한다.

 

프로그램이 메모리에 올라가면 프로세스가 되는 인스턴스와가 일어나고, 이후 운영체제의 CPU 스케줄러에 따라 CPU가 프로세스를 실행한다.

 

프로세스와 컴파일 과정

프로세스는 프로그램이 메모리에 올라 인스턴화가 된 것이다. 컴파일러가 컴파일 과정을 통해 컴퓨터가 이해할 수 있는 기계어로 변역하여 실행할 수 있는 파일을 만들게 된다. 

 

컴파일 과정

  • 전처리: 소스 코드의 주석을 제거하고, #include 등 헤더 파일을 병합하여 매크로로 치환한다.
  • 컴파일러: 오류처리, 코드 최적화 작업을 하며 어셈블러어로 변환한다.
  • 어셈블러: 목적 코드로 변환한다. (.o 파일로)
  • 링커: 라이브러리 함수 또는 다른 파일들과 목적 코드를 결합하여 실행 가능한 파일로 만든다. (.exe 파일로)

정적 라이브러리: 프로그램 빌드시 라이브러리가 제공하는 모든 코드를 실행 파일에 넣는 방식이다. => 메모리 효율성이 떨어지지만, 외부 의존도가 줄어든다.

동적 라이브러리: 실행시 필요할 때만 DLL이라는 함수 정보를 통해 참조하여 라이브러리를 쓰는 방법이다. => 외부 의존도가 늘어나지만, 메모리 효율성이 올라간다. 

 

프로세스의 상태

  • 생성 상태: fork(), exec()으로 생성. 이때 PCB가 할당됨. 
    • fork(): 복사
    • exec(): 새로운 프로세스 생성
  • 대기 상태: 메모리 공간이 충분하면, 메모리를 할당 받고 아니면 대기한다. CPU 스케줄러로부터 CPU 소유권이 넘어오기를 기다리는 상태이다.
  • 대기 중단 상태: 메모리 부족으로 일시 중단된 상태이다.
  • 실행 상태: CPU 소유권과 메모리를 할당 받고 인스트럭션을 수행 중인 상태이다. CPU burst가 일어났다고 한다.
  • 중단 상태: 어떤 이벤트가 발생한 이후, 기다리며 프로세스가 차단된 상태이다.
    • 예시) I/O 디바이스에 대한 인터럽트
  • 일시 중단 상태: 대기 중단과 유사하다. 중단 상태에서 프로세스가 실행되려 했지만, 메모리 부족으로 일시 중단된 상태이다.
  • 종료 상태: 메모리와 CPU 소유권을 모두 놓고 가는 상태. (자연스럽게 종료가 있고, 부모가 자식을 종료시키는 경우도 있다.)

프로세스 메모리 구조

  • 스택: 지역변수, 매개 변수 => 실행되는 함수에 의해 늘었다 줄었다 한다. 함수가 호출될 때마다 호출될 때의 환경 등 특정 정보가 스택에 계속해서 저장된다.
  • 힙: 동적으로 할당되는 변수들을 담는다. (malloc(), free())
  • 데이터: BSS segment와 Data segment로 나뉜다.
    • BSS segment는 전역 변수나 static, const 이면서 0으로 초기화 또는 초기화가 어떤 값으로도 안된 변수들이 저장된다.
    • Data segment는 전역 변수나 static, const 이면서 0이 아닌 어떤 값으로 초기화된 변수가 저장된다.
  • 코드: 프로그램의 코드가 들어간다. 

PCB

  • 프로세스에 대한 metadata를 저장한다. 프로세스가 생성되면 OS는 PCB를 생성한다.
  • PID, 상태, 권한 등의 정보를 담고 있다.
  • 컨텍스트 스위칭: PCB를 기반으로 프로세스의 상태를 저장하고 로드시키는 과정을 말한다.
    • 한 프로세스에 할당된 시간이 끝나거나 인터럽트에 의해 발생한다. 
    • 비용 -> 캐시미스: 컨텍스트 스위칭 시 가지고 있는 메모리의 주소가 그대로 있으면 안되므로 캐시를 클리어 한다. 그래서 캐시 미스가 발생하게 된다. 
    • 쓰레드는 공유하는 메모리가 있어 컨텍스트 스위칭 비용이 적다. 

멀티 프로세싱

여러개의 프로세스, 즉 멀티 프로세스를 통해 동시에 두가지 이상의 작업을 수행할 수 있는 것이다. 하나 이상의 일을 병렬적으로 처리 가능하고, 특정 프로세스의 메모리, 프로세스 중 일부에 문제가 발생해도 다른 프로세스를 이용해서 처리 가능하다. => 신뢰성이 높다.

멀티 프로세싱은 하드웨어 관점에서 봤을 때, 여러개의 프로세서로 작업 처리하는 것을 의미하기도 한다. 

 

  • IPC: IPC는 프로세스끼리 데이터를 주고 받고 공유 데이터를 관리하는 매커니즘이다. 
    • 종류: 공유 메모리, 파일, 소켓, 익명 파이프, 명명된 파이프, 메시지 큐
    • 모두 메모리를 완전히 공유하는 쓰레드보다는 속도가 느리다.
    • 공유 메모리
      • 여러 프로세스들에게 동일한 접근 권한이 부여되어 프로세스가 서로 통신할 수 있도록 공유 메모리를 생성해서 통신하는 것이다.
      • 기본적으로 각 프로세스들끼리는 서로의 메모리에 접근할 수 없지만, 공유 메모리를 통해 여러 프로세스가 하나의 메모리를 공유 가능하다.
      • 어떠한 매개체를 이용하는 것이 아니라 메모리 자체를 공유해서 불필요한 데이터 복사의 오버헤드가 발생하지 않아 가장 빠르다. 그리고 여러 프로세스가 공유하기 때문에 동기화가 필요하다. 
    • 파일
      • 디스크에 저장된 데이터 또는 파일 서버에서 제공한 데이터를 말하며, 이를 기반으로 프로세스간 통신을 할 수 있다.
    • 소켓
      • 동일한 컴퓨터의 다른 프로세스나 네트워크의 다른 컴퓨터로 네트워크 인터페이스를 통해 전송하는 데이터를 의미한다. TCP와 UDP가 있다.
    • 익명 파이프(unnamed pipe)
      • 프로세스간에 FIFO 방식으로 읽히는 임시 공간인 파이프를 이용하여 데이터를 주고 받는다. 단방향 방식의 읽기, 쓰기 전용 파이프를 만들어서 사용한다.
      • 부모, 자식 프로세스 간에만 사용 가능하다.
    • 명명된 파이프(named pipe)
      • 파이프 서버와 하나 이상의 파이프 클라이언트 간의 통신을 위해 명명된 단방향 또는 양방향 파이프를 말한다. 
      • 클라이언트/서버 통신을 위한 별도의 파이프를 제공한다. 여러개의 파이프를 동시 사용 가능하고, 컴퓨터의 프로세스끼리 또는 다른 네트워크 상의 컴퓨터와도 통신 가능하다. 
    • 메시지 큐
      • 메시지를 큐에서 관리한다. 
      • 커널의 전역 변수 형태 등 커널에서 전역적으로 관리된다.
      • 다른 IPC에 비해 사용 방법이 직관적이다. 단지 몇줄의 코드만 추가하면 된다.
      • 공유 메모리에서 읽기, 쓰기가 잦으면 동기화가 늘어난다. 그래서 메시지 큐를 사용하면 좋다. 

쓰레드와 멀티 쓰레딩

  • 쓰레드
    • 쓰레드는 프로세스의 실행 가능한 가장 작은 단위이다. 프로세스는 여러 쓰레드를 가질 수 있다. 쓰레드는 코드, 데이터, 힙을 쓰레드끼리 공유한다. 그 외의 영역은 각각 생성된다.
  • 멀티 쓰레딩
    • 프로세스 내 작업을 여러개의 쓰레드가 한다. 멀티 쓰레드로 처리하는 기법이다.
    • 쓰레드까지 자원을 공유해서 효율성이 높다.
    • 새 프로세스를 생성하는 것 대신 새 쓰레드를 생성해 사용하는 서버의 경우 훨씬 적은 리소스를 소비하여 한 쓰레드가 중단되어도 다른 쓰레드는 실행 중이라 중단되지 않는 빠른 처리가 가능하다.
    • 동시성에도 큰 장접이 있지만, 한 쓰레드에 문제가 생기면 다른 쓰레드에도 문제가 생길 수 있다.

공유 자원과 임계 영역

  • 공유 자원(shared resource)
    • 시스템 안에서 각 프로세스, 쓰레드가 함께 접근할 수 있는 자원이나 변수 등을 의미한다.
    • 동시에 접근해서 읽거나 쓰려고 하는 것을 경쟁 상태(race condition)이라고 한다.
    • 동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결과에 영향을 줄 수 있다. 
  • 임계 영역(critical section)
    • 둘 이상의 프로세스나 쓰레드가 공유 자원에 접근할 때 순서 등의 이유로 실행 결과가 달라질 수 있는 코드의 영역이다. 
    • 뮤텍스와 세마포어, 모니터로 해결 가능하다.
      • 모두 상호 배제, 한정 대기, 융통성이라는 조건을 만족한다. 토대가 되는 매커니즘은 잠금(lock)이다.
        • 상호 배제: 한 프로세스가 임계 영역에 들어갔을 때, 다른 프로세스는 들어갈 수 없다.
        • 한정 대기: 특정 프로세스가 영원히 임계 영역에 들어가지 못하면 안된다.
        • 융통성: 만약 어떠한 프로세스도 임계 영역을 사용하지 않는다면, 임계 영역 외부의 어떠한 프로세스도 임계 영역에 들어갈 수 있으며, 이 때 프로세스끼리도 서로 방해할 수 없다. 
      • 뮤텍스
        • 프로세스나 쓰레드가 공유 자원을 lock()을 통해 잠금 설정하고, 사용한 후에는 unlock()을 통해 잠금 해제하는 객체이다.
        • 잠금이 설정되면 다른 프로세스나 다른 쓰레드는 접근할 수 없다.
        • 잠금과 잠금 해제 상태만 가진다.
      • 세마포어
        • 정수 값과 두가지 함수 wait(P함수), signal(V함수)로 공유 자원에 대한 접근을 처리한다.
        • wait()는 자신의 차례가 올 때까지 대기하는 것. signal()은 다음 프로세스로 접근을 넘겨주는 것이다.
        • 조건 변수가 없고 프로세스나 쓰레드가 세마포어 값을 수정할 때 다른 프로세스나 쓰레드는 수정할 수 없다.
        • 바이너리 세마포어
          • 0과 1의 값만 가진다. 뮤텍스와 비슷하지만, 뮤텍스는 잠금 매커니즘, 세마포어는 신호 매커니즘이다.
        • 카운팅 세마포어
          • 여러개의 값을 가질 수 있다. 여러 자원에 대한 접근을 제어한다. 
      • 모니터
        • 둘 이상의 쓰레드나 프로세스가 공유 자원에 안전하게 접근할 수 있도록 공유 자원을 숨기고, 해당 접근에 대해 인터페이스만 제공한다.
        • 모니터 큐를 이용하여 공유 자원에 대한 작업들을 순차적으로 처리한다.
  • 교착 상태
    • 두개 이상의 프로세스들이 서로가 가진 자원들을 대기하여 작업이 중단된 상태이다.
    • ex) 프로세스 A가 프로세스 B의 어떤 자원을 요청하는데, B도 A가 점유한 자원을 요청한다.
    • 원인
      • 상호 배제: 한 프로세스가 자원 독점. 다른 프로세스는 접근 불가
      • 점유 대기: 특정 프로세스가 점유한 자원을 다른 프로세스가 요청
      • 비선점: 다른 프로세스의 자원을 강제로 가져올 수 없음
      • 환형 대기: 서로가 서로의 자원을 요구함.
    • 해결 방법
      • 자원 할당 시 애초에 조건이 성립되지 않게
      • 교착 상태 가능성이 없을 때만 자원이 할당되며, 프로세스 당 요청할 자원들의 최대치를 통해 자원할당 가능 여부를 파악하는 '은행원 알고리즘'을 쓰기
        • 은행원 알고리즘: 총 자원의 양과 현재 할당한 자원의 양을 기준으로 안정 또는 불안정 상태로 나누고, 안정 상태로 가도록하는 알고리즘
      • 교착 상태가 발생하면 사이클이 있는지 보고, 이에 관련된 프로세스는 한 개씩 지운다.
      • 교착 상태는 매우 드물게 일어나서 이를 처리하는 비용이 더 크다. 그래서 사용자가 작업 종료하게 한다.
        • 현재 OS는 이 방법을 채택했다. '응답 없음'이 뜨는 경우 중 일부이다. 
728x90

'CS' 카테고리의 다른 글

4.1 데이터베이스의 기본  (1) 2024.09.20
3.4 CPU 스케줄링 알고리즘  (1) 2024.09.19
3.2 메모리  (4) 2024.09.15
3.1 운영체제와 컴퓨터  (0) 2024.09.12
2.5 HTTP  (1) 2024.09.07