본문 바로가기
컴퓨터 공학

[기술면접대비] 1. 운영체제와 프로세스

by 물고기고기 2023. 12. 27.

DALL-E 생성이미지

기술 면접 대비 스터디로 https://product.kyobobook.co.kr/detail/S000208504237 를 스터디중인데 해당 내용 요약정리 및 보면서 추가로 공부한것들을 백업하고자 한다.

 


 

1. 운영체제


운영체제 : 하드웨어와 응용프로그램 사이에서 사용자가 컴퓨터를 사용할 수 있는 환경을 제공하는 시스템(소프트웨어)
CPU : 주 기억장치 & 보조 기억장치
메모리 계층구조 : (레지스터 - 캐시메모리)(여기까지가 CPU) - RAM - 하드디스크


+) CPU는 하나의 프로세스만 처리할 수 있어서 멀티 프로세스 환경에선 스케쥴링 알고리즘이 사용된다 -> 주로 사용되는 스케쥴링 알고리즘은?

커널 : 응용프로그램 <> CPU,메모리,외부기기 사이에서 자원관리를 해줌
예를 들어 CPU 스케쥴링이나 메모리 관리, 파일 시스템 관리 등을 함
시스템 콜 : 사용자가 하드웨어 자원에 접근하지 못하도록 운영체제는 사용자 모드와 커널 모드를 나누는데, 사용자 모드에서 프로세스가 자원에 접근하려면 시스템 콜을 호출해 커널에 요청하면 된다.
즉, 시스템 콜이라는건 즉 사용자 모드에서 커널 모드로 접근하도록 해주는 시스템 함수임.

+) 시스템 콜의 대표적인 예시로는 fork(), wait() 등이 있다. -> 어떻게 동작?, 리눅스 개발언어는 C니까 C 코드를 한번 볼것
참조링크 : https://jehwanyoo.net/2020/10/19/process-system-call/

 

프로세스 핵심 시스템 콜을 알아보자 (fork, wait, exec, dup, dup2, pipe)

개요 오늘은 프로세스에서 중요한 운영체제 몇가지 시스템 콜에 대해 알아보겠습니다. 아래의 개념을 알아야 운영체제의 기본 동작과 sh 프로그램을 이해할 수 있습니다. 예제에서는 예외처리

jehwanyoo.net

 

2. 프로세스


프로세스 : 컴퓨터에서 실행중인 하나의 프로그램이며 실행될때 독립된 메모리 영역을 매번 할당 받는다. 프로세스 끼리는 서로의 메모리 영역에 접근할 수 없다.
프로세스에 할당된 메모리 영역의 경우 : 운영체제영역(PCB) - 프로세스들 - 사용자영역
프로세스 메모리 영역의 구조 : 스택 - (빈 메모리 공간) - 힙 - 데이터 - 코드(text)


코드 : 실행할 프로그램의 코드가 저장됨, CPU는 이 영역에서 명령어를 하나씩 가져와 처리
데이터 : 전역변수, 정적 변수가 들어감 프로그램 시작 시 할당되고 종료시 소멸됨
스택 : 잠시 사용되었다가 사라지는 데이터들을 저장함, 컴파일 시 크기가 결정됨
 +) 이때 코드, 데이터, 스택은 컴파일 시에 영역의 크기를 계산해 메모리 영역을 결정함
 : 동적 데이터 영역, 런타임 시에 크기가 결정됨, 스택에서 변수를 할당하면 힙에서 원하는 크기만큼 할당해 사용하는 구조

스레드 : 프로세스에서 실제로 실행되는 흐름의 단위, 지역 변수를 저장할땐 스택을 할당 받고, 전역 변수 같은 힙 영역은 다른 스레드와 공유한다.
PCB(프로세스 제어 블록) : 프로세스 정보를 저장하는 블록
고유 PID, 부모 프로세스의 PID, 자식 프로세스의 PID, 프로그램 카운터(다음 실행할 명령어의 주소), 프로세스의 우선순위, 메모리 제한 등을 저장

부모 프로세스와 자식 프로세스의 예시 -> 웹 서버와 서블릿간의 관계
* 클라이언트가 웹 브라우저를 통해 특정 URL에 요청을 보내면, 이 요청은 웹 애플리케이션 서버에 도달합니다.
* 웹 애플리케이션 서버는 요청을 분석하여 적절한 서블릿을 찾습니다.
* 해당 서블릿이 시작되어 (자식 프로세스로서) 클라이언트의 요청을 처리합니다. 처리 과정에서 데이터베이스 조회, 계산 등의 작업이 포함될 수 있습니다.
* 처리가 완료되면, 서블릿은 결과를 웹 애플리케이션 서버에 전달합니다.
* 웹 애플리케이션 서버는 이 결과를 HTTP 응답 형태로 클라이언트에게 전송합니다.



+) 그러면 하나의 자바 서버를 띄우면 얘한테 걸린 부모 프로세스 PID가 어떤게될수있을까? : 해당 자바 서버를 시작한 셸(shell) 또는 애플리케이션의 PID가 됩니다. (명령 프롬프트같은거)

프로세스의 생성 : fork()의 동작 방식을 간략하게 설명하자면

부모 프로세스에서 fork() 실행 
-> 자식 프로세스 고유 PID 부여, 이때 자식은 또다른 자식이 없으니까 0 return 
-> 부모 프로세스는 자식 프로세스의 고유 PID 받음, 자식이 있으니 해당 PID return


프로세스의 상태도: 생성 > 준비 > 대기 > 실행 > 종료를 거침
*  생성 > 준비 : 생성 상태의 프로세스가 OS로 승인 받은 뒤 준비 큐에 추가
*  준비 > 실행 : 준비큐에 있는 프로세스 중 우선순위가 높은 프로세스가 실행상태가 됨
*  실행 > 준비 : CPU독점 방지를 위해 타임아웃이 되어 준비상태로 변경
*  실행 > 대기 : 입출력 또는 이벤트로 대기상태
*  대기 > 준비 : 입출력 또는 이벤트가 완료되어 준비상태
*  실행 > 종료

 

실행 > 준비 과정이 조금 모호한가? 예시? 한개가 실행이 너무 오래걸리면 잠깐 실행을 멈추고 다른걸 실행함, 그러니까 한 30%실행했다가 다른 프로세스가 끝나면 다시 한 50%해서 계속 실행하는셈, 멀티태스킹 운영 체제에선 일반적인 상황임

실행 > 대기 상태의 예시 파일 읽기/쓰기 같은 요청을 하는 경우 I/O 작업이 완료될때까지 대기하는 것



멀티 프로세스와 멀티 스레드

동시성 : 하나의 코어에서 여러 작업을 번갈아 처리하는 방식 -> CPU에서 여러 작업을 번갈아 가며 처리하는 작업을 콘텍스트 스위칭이라고 함
병렬성 : CPU가 여러개 있어서 각 작업을 동시 처리하는 방식(물리적으로 정말 동시에 여러개 처리)

멀티 프로세스 : 응용 프로그램 하나를 여러 프로세스로 구성하는 것
CPU는 하나의 작업만 처리할 수 있으니 콘텍스트 스위칭 작업이 이루어져야하는데, 이때 기존 프로세스가 쓰던 메모리를 다른 프로세스로 교체할때 사용하는 시간과 메모리를 오버헤드라고 한다. 그리고 프로세스간 공유할 자원이 있다면 IPC라는 통신 메커니즘을 통해 자원을 공유한다.(공유할 메모리를 직접 참조하는 것보다 비효율적임)

응용 프로그램 멀티 프로세스 예시 우리가 사용하는 웹 브라우저에서 멀티 프로세스가 적용된다. 하나의 탭에서 문제가 생겼을때 다른 탭에 영향을 주지 않기 때문


+) IPC
* IPC는 서로 다른 프로세스들이 데이터를 주고받거나, 상태 정보를 공유하거나, 작업을 조정하기 위해 사용되는 기술입니다.
* IPC의 예로는 파이프, 메시지 큐, 공유 메모리, 소켓, 시그널 등이 있습니다.
* 이러한 기술들은 프로세스들이 독립적으로 실행되는 동안에도 서로 정보를 교환하거나 협력할 수 있도록 해줍니다.

멀티스레드 : 스레드 간에 공유하는 메모리 영역이 있음. 콘텍스트 스위칭 시에 오버헤드가 적게 발생, IPC를 사용하지 않음
그러나 스택 영역을 다른 스레드와 함께 사용하므로 공유 자원에 대한 동기화가 필수이며, 스레드에 문제가 생기면 다른 스레드에 영향을 미치기도 한다.

+) 프로세스가 스레드보다 상위 개념인줄 알았는데 그렇다면 특정 문제를 해결할때 멀티스레드냐 멀티프로세스냐를 고를수 있었던건가.. > 맞음 장단점은 이거

멀티프로세스 멀티스레드
    * 장점: 안정성이 높고 프로세스 간 격리가 잘 이루어집니다. 한 프로세스의 실패가 다른 프로세스에 영향을 미치지 않습니다.
    * 단점: 오버헤드가 크며, 프로세스 간 통신 비용이 높습니다.
* 장점: 리소스 공유가 용이하며, 스레드 간 통신 비용이 낮습니다. 컨텍스트 스위칭 비용이 프로세스에 비해 상대적으로 낮습니다.
    * 단점: 안정성과 보안 문제가 발생할 수 있습니다. 하나의 스레드에서 발생한 문제가 전체 프로세스에 영향을 줄 수 있습니다.


콘텍스트 스위칭 : CPU에서 처리 중인 프로세스가 중간에 변경되어도 이전에 실행하던 코드를 이어서 실행할 수 있는 이유는 PCB에 관련 정보값들이 저장되어 있기 때문이다.
프로그램 카운터 : 프로세스가 이어서 처리해야하는 명령어의 주소 값
스택 포인터 : 스택 영역에서 데이터가 채워진 가장 높은 주소 값

프로세스 동기화

프로세스 동기화 : 프로세스 또는 스레드에서 같은 자원에 접근할 때 접근 순서에 따라 결과 값이 달라진다. 일관성이 유지되려면 프로세스 동기화가 필요함
경쟁 상태 : 공유 자원에 동시에 접근해 경쟁하는 상태
임계 영역 : 공유 자원에 접근할 수 있고 접근 순서에 따라 결과가 달라지는 코드 영역

결국 임계 영역에 여러 접근이 동시에 발생하는 것을 방지하려면 3가지를 충족해야함

  1. 상호배제 기법 : 어떤 프로세스가 임계 영역을 실행 중이면 다른 프로세스가 임계 영역에 접근할 수 없음
  2. 진행 : 임계 영역을 실행중인 프로세스가 없을 때 다른 프로세스가 임계 영역을 실행
  3. 한정된 대기 : 임계 영역에 접근 요청했을때 무한히 기다리지 않음



상호배제 기법 두가지

뮤텍스 : 락을 가진 프로세스만이 공유 자원에 접근할 수 있게 하는 방법, 임계 영역에 먼저 접근한 프로세스가 락을 해제하기전까지 다른 프로세스들이 대기하는 구조(락킹 메커니즘) -> 임계영역에 접근하지 못한 프로세스는 락을 얻기위해 반복문을 돌며 확인함(스핀락,바쁜대기)
세마포어 : 공유 자원에 접근할 수 있는 프로세스의 수를 제한해 접근을 제어하는 방법, 키 n개를 지정하고 이 중 하나를 가진프로세스만이 접근 허용(시그널링 메커니즘)

-> 요약하자면 뮤텍스는 단일 자원에 대한 접근 제어에 사용, 세마포어는 여러개의 유사한 자원에 대한 접근 제어

그런데 멀티 프로세스는 각 프로세스가 독립된 메모리 공간을 가지고 있기 때문에 공유자원이랄게 없는데 경쟁상태가 일어나지 않는걸까? 
멀티프로세스 환경에서는 각 프로세스가 독립된 메모리 공간을 가지고 있기 때문에, 전통적인 의미에서의 '공유 자원'에 대한 경쟁은 일반적으로 발생하지 않습니다. 즉, 프로세스 내부의 자원은 다른 프로세스와 공유되지 않으므로, 내부 자원에 대한 접근 충돌이나 경쟁 상태는 발생하지 않습니다.
그러나, 프로세스 간에 특정 유형의 외부 자원(예: 파일 시스템, 데이터베이스, 네트워크 소켓 등)을 공유할 경우, 이러한 자원에 대한 동시 접근에 의한 경쟁 상태는 발생할 수 있습니다.


+) 프로세스 동기화 중 경쟁상태의 예시?
+) 동기/비동기/블로킹/논블로킹

교착상태 : 2개 이상의 프로세스가 서로의 자원을 요구하며 기다리는 상태
아래의 4가지 조건으로 인해 교착상태 발생

  1. 상호배제 : 하나의 공유 자원에 하나의 프로세스만 접근
  2. 점유와 대기 : 프로세스가 최소 하나의 자원을 점유중인 상태에서 추가로 다른 프로세스에서 사용 중인 자원을 점유하기 위해 대기
  3. 비선점 : 다른 프로세스에 할당된 자원을 뺏을 수 없다.
  4. 환형 대기 : 프로세스가 자신의 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원 요구


각각의 해결 방법 -> 4가지 조건 중 한가지만 제거하면 교착상태 방지 가능

  1. 상호배제 부정 : 여러 프로세스가 하나의 공유 자원 사용 가능
  2. 점유 대기 부정 : 프로세스가 실행되기 전에 필요한 모든 자원을 미리 할당함으로써 프로세스 대기를 없앰, 혹은 프로세스가 자원을 점유하지 않은 상태에서만 자원을 요구하도록 함
  3. 비선점 부정 : 자원을 점유한 프로세스가 다른 자원을 요구할 때 점유한 자원을 반납
  4. 환형 대기 부정 : 자원을 선형 순서로 정렬해 고유번호 할당. 각 프로세스에서 요구할 수 있는 번호의 방향을 정해 한쪽 방향으로만 요구



IPC(Inter Process Communication)
1. 공유 메모리 : 프로세스 간에 공유 가능한 메모리를 구성해 자원 공유 -> 동기화 문제 발생
2. 소켓 : 네트워크 소켓을 이용해 프로세스 간 필요한 자원이 있으면 그때그때 통신하는 방식
3. 세마포어 : 접근하는 프로세스를 제어해 공유 자원을 관리
4. 파이프 : FIFO 형태의 메모리인 파이프를 이용해 프로세스 간 자원을 공유하는 방식
5. 메세지 큐 : 큐를 이용해 프로세스 간 메세지를 주고받는 방식

좀비 프로세스와 고아 프로세스
좀비 프로세스 : 자식 프로세스가 종료 되었는데 부모 프로세스가 자식의 종료 상태를 회수하지 않아 남겨진 자식 프로세스
고아 프로세스 : 부모가 자식보다 먼저 종료되는 경우 계속 남아 있는 자식 프로세스
-> 자식 프로세스가 무조건 부모 프로세스보다 먼저 종료되도록 PID를 1로 바꿔주면 자식 프로세스를 부모 프로세스보다 먼저 실행돼 좀비 프로세스가 되는 것 방지 가능

댓글