3 분 소요

Process란?

  • Process란 무엇인가 알기전에 Program과 Process에 어떤 차이가 있는지에 대해 알아보자.
  • Program이란 H/W에 저장된 실행 파일이다. Process와의 차이는 프로그램은 단지 작업을 수행하기 위한 명령어의 모음일뿐, 그 자체로서는 어떠한 일도 하지 않는다. 예를 들자면 흔히 인터넷 웹 브라우저로 사용하는 “Chrome.exe” 실행 파일 자체는 우리가 직접 실행을 하기 전까지는 어떠한 Task도 수행하지 않는다. 우리가 Chrome.exe 파일을 실행하고 나서야 브라우저 창이 뜨게되고 그 때부터 OS에서 관리해야 하는 Tasks가 되는 것이다.
  • 결국 Process란 Computer memory에서 일을 하기 위한 작업 (task) 단위라고 볼 수 있다.

Process의 Memory 구조

Process가 OS상에서 동작하기 위해서는 컴퓨터가 연산을 하기 위해 사용하는 Memory 구조로 구성되어 있어야만 한다. Process의 Memory 구조는 Memeory address의 아래에서 위쪽 순서로 Code, Data, Heap, Stack 영역이 할당된다. 각 항목들에 대해서 자세히 알아보자.

alt 출처 : https://media.geeksforgeeks.org/wp-content/uploads/memoryLayoutC.jpg

  1. Code : 쉽게 말해 명령어의 집합이라고 보면 된다. OS는 프로세스 실행을 위해 이곳에서 명령어를 Load 한다.
  2. Data : Programmer에 의해서 초기화된 global 변수나 static 변수를 저장하는데 사용된다. 좀 더 세부적으로 나누면 초기화된 static, global 변수를 저장하는 공간과 그렇지 않은 static, global 변수를 저장하는 공간으로 나뉘게 된다. 초기화 하지 않은 것은 kernel에 의해서 자동으로 초기화 한다. OS마다 조건이 다를 것이므로 조심해야 한다.
  3. Heap : 동적 memory가 위치할때 사용되는 영역이다. Heap 영역은 Data 영역의 가장 위쪽부터 시작된다. C에서는 malloc, realloc, free 등과 같이 동적 메모리 할당 및 반납을 할때 조절이 되는 곳이다.
  4. Stack : Heap과는 반대로 위에서 아래로 메모리를 적재한다. 이곳에는 함수 호출, 로컬 변수 등을 저장하는데 사용한다.
    • Stack 영역이 왜 필요하나? 라고 생각을 해볼 수 있다. Recursive Function을 생각해보자. 아래 함수의 경우 recur(5)를 호출한다고 하면 recur(n-1) 부분으로 인해 recur(4) ~ recur(1) 이 호출될 것이다. recur 에서는 a라는 지역변수가 매번 사용되는데, 똑같은 이름의 recur 함수에서 a라는 변수를 어떻게 구분을 할 것인가? 몇 번째 recur에서 a가 나오고 있는지에 대해 정보가 필요할 것이다. 이 역할을 Stack 에서 추적하기 위해 사용한다. 내용이 이해가 잘 되지 않는다면 https://stackoverflow.com/questions/10057443/explain-the-concept-of-a-stack-frame-in-a-nutshell 를 참고하자.
         int recur ( int n )
         {
             if ( n == 0 ){
                 return 0;
             }
      
             int a = n;
             a += recur(n-1);
             return a;
         }
      
    • Default Stack 사이즈는 Compiler나 OS 별로 다르다. C++의 경우 다음과 같다. linux에서는 ulimit -s byte 로 스택사이즈 조정이 가능하다.
      • glibc i386, x86_64: 7.4 MB
      • Tru64 5.1: 5.2 MB
      • Cygwin: 1.8 MB
      • Solaris 7..10: 1 MB
      • MacOS X 10.5: 460 KB
      • AIX 5: 98 KB
      • OpenBSD 4.0: 64 KB
      • HP-UX 11: 16 KB
      • Visual Studio : 1 MB

프로세스의 계층구조

  1. PID ( Process ID )
    • 프로세스는 고유한 자신만의 ID를 가지고 있다. 사용자는 Process ID를 통해 Process를 식별할 수 있다.
    • PID = 1은 init 프로세스이다. Kernel에 의해 생성되는 첫번째 프로세스고 유일하게 부모 프로세스가 없다.
    • Linux에서는 ps 명령어를 통해 확인 가능하다.
    • 현재 Process ID를 출력하려면 echo $$ 명령어를 사용하자.
  2. 부모 프로세스와 자식 프로세스
    • 프로세스는 자신 이외의 또 다른 Process를 가질 수 있다. 이를 자식프로세스라고 한다.
    • 생각보다 많은 것들이 Parent - Child의 관계를 가진다. 예를 들어 Linux에서 ls 명령어를 수생하더라도 이는 Bash ( Parent ) - ls ( Child ) 의 관계를 가진다.
      • 만약 shell script에서 sleep을 실행하더라도 script ( parent ) - sleep ( child ) 의 관계가 형성된다.
  3. 프로세스 종료 처리
    • 모든 Child 프로세스는 종료시점에 Garbage를 남기게 된다. 이는 부모에서 제거를 해줘야하는데 종료 시점을 알리기 위해 프로세스는 신호를 보낸다.
    • 정수형으로 신호를 알리고 정상 종료되면 0, 이외의 숫자는 뭔가 문제가 발생했다는 것을 뜻한다.
    • core dump 생성 여부 및 [1]시그널을 통해 종료가 되었는지 등을 알 수 있다.
    • OS, Program Language 별로 정의 되어 있다. ( 참고 : https://ko.wikipedia.org/wiki/%EC%A2%85%EB%A3%8C_%EC%83%81%ED%83%9C )
    • echo $? 를 통해 직전의 프로세스에서 종료코드를 확인할 수 있다.
      1
      2
      3
      4
      
        cd "not exists dir"
        >> can't access ~~~ 
        echo $?
        >> 2
      
  4. 고아 프로세스와 좀비 프로세스
    1. 고아 프로세스
      • 자식프로세스 보다 부모프로세스가 먼저 Kill 되었을 경우
      • Linux에서는 고아 프로세스는 Init 프로세스의 자식으로 할당된다.
    2. 좀비 프로세스
      • 부모에 의해 종료가 되어야 하나 그렇지 않고 계속 남아있는 프로세스다.
      • 부모에게 signal을 보내고 Kill 되어야 하나 그렇지 못한 경우 생기게 된다. 자원이 완벽하게 정리가 되지 않기 때문에 낭비가 발생한다.

표준 스트림 ( standard streams )?

  • 모든 프로세스가 기본적으로 가지고 있는 입출력 방식이다.
  • 표준 입력 ( std in ), 표준 출력 ( std out ), 표준 에러 ( std error ) 로 구성되어 있다.
  • 흔히 bash 안에서 사용자와 메시지를 주고받는 프로그램들을 이용할때 사용되는 스트림이다.
  • 파일에 대한 입출력 창구는 파일 디스크립터를 통해 관리된다. alt

프로세스의 종류

  1. 포어그라운드 프로세스
    • 쉘의 표준 입력이 연결되어 있는 프로세스
    • 포어그라운드에서 백그라운드로 전환하려면 ctrl + z 이후 bg 명령어를 실행해주면 된다.
  2. 백그라운드 프로세스
    • 쉘의 표준 입력이 연결되어 있지 않은 프로세스
    • 프로그램을 실행할 때 뒤에 &를 붙여주면 백그라운드로 실행된다. ex) sh script.sh &
    • 포어그라운드로 전환하려면 다음과 같이 진행한다.
      • jobs -l 명령어로 background process 리스트의 index 확인.
      • fg index 명령어로 포어그라운드로 전환.
  3. 데몬 프로세스
    • “보이지 않는 곳에서 어떤 일을 하는 프로세스” 의 대명사다.
    • 백그라운드 프로세스로 동작하기 위해 만들어졌다.
    • 표준 스트림을 갖고 생성되지만 모두 닫아버리고 User와는 아무런 소통을 할 수 없다.
    • 자기 자신의 부모를 Init 프로세스로 변경한다.
    • 모니터링 같은 프로그램이 데몬프로세스로 생성된다고 한다.

참고 페이지

  • https://stackoverflow.com/questions/1825964/c-c-maximum-stack-size-of-program
  • https://www.geeksforgeeks.org/memory-layout-of-c-program/?ref=gcse





[1]: 비동기 이벤트 처리를 위한 프로세스간 통신 방법이다. Inter Process Cominucate의 여러 방법 중 하나이다.

태그:

카테고리:

업데이트:

댓글남기기