Linux Process 관리

mohadang·2023년 3월 11일
0

Linux System Programming

목록 보기
7/9
post-thumbnail
post-custom-banner

Linux Process 실행

프로세스 실행에는 2가지 방법이 있다.

  • Executing a new program
    • 기존 program은 중지되고 Binary program을 읽어서 자신을 호출한 process의 메모리 영역에 덮어 씀.
    • A -> B 프로세스 전환이 일어난다. 그래서 사용시 주의 필요하다.
  • Creating a new process(forking)
    • 자신을 호출한 procedss(parent process)를 복사하여 새로운 process(child process) 생성
    • forking : fork의 날처럼 끝으로 가면서 나뉘어 진다.

Executing a new program(A -> B 프로세스 전환)

실행 관련 API

  • 끝에 p가 붙어 있는 것은 알려져 있는 경로(환경 변수 PATH)에서 찾아서 실행

이 프로그램을 실행하면 "--> After exec function\n"은 출력되지 않는다.
이유는 execlp 호출 하면서 기존 프로그램은 중지되고 ls 프로세스가 기존 프로그램의 메모리 영역을 덮어 쓴다.
기존 프로그램이 중지 되었기에 더 이상 기존 프로세스의 진행이 불가능 하여 다음 출력을 할 수 없다.

execlp 호출시 2번째 인자에 ls를 다시 넣는 이유는 argv[0]는 실행한 프로그램 이름이기 때문이다.

Creating a new process(forking)

#include <unistd.h>
pid_t fork(void);

fork() system call : 자신을 복제(메모리 복사)해 새로운 process를 생성(Child process)한다.
부모와 자식 프로세스의 수행은 동시 진행된다(독립적으로 실행 됨, 같은 program binary 수행)
성공적으로 호출하면 부모 프로세스는 자식 프로세스의 PID를 반환받고 자식 프로세스는 0을 반환 받는다.

병렬 처리에 사용하기에 좋을 것이다.

fork 과정

자식 프로세스에 상속 되는 정보

  • RUID, EUID, RGID, EGID, setuid, setgid
  • Environment variables, Opened File descriptors
  • Working directory, Signal handling setup, resource limit, Etc...

자식 프로세스에 상속 안되는 정보

  • PID(새 ID)
  • PPID(Parent PID)
  • tms structure
  • 자원 사용 정보들
    • Resources statics
    • Pending signals
    • File locks, Etc

fork handling

int main(void) {
  pid_t pid;
  switch (pid = fork()) {
    case -1:
      // error
      break;
    case 0: // child process handling
      printf("pid:%d, ppid:%d\n", (int)getpid(), (int)getppid());
      if (execlp("ls", "ls", "-a", (char*)NULL) == -1) {
        perror("execlp");
        exit(1);
      }
      break;
    default: // parent process handling
      printf("pid:%d, ppid:%d, child pid:%d\n", (int)getpid(), (int)getppid(), (int)pid);
      break;      
  }
  return 0;
}

execlp("ls", "ls", "-a", (char*)NULL)를 호출하여 자식 프로세스는 ls로 대체된다. 현실적인 자식 프로세스 사용버이다.

Linux Process 종료

Process가 종료 되면, 어떻게 종료 되었는지를 exit status에 저장
child process의 종료 상태를 parent process로 전달 가능

#include <stdlib.h>
void exit(int status);// status : 전달할 exit status

status & 0377(8진수)이 부모에게 전달됨

Process의 종료 과정

  1. atexit(3)에 등록된 함수들을 등록 역순으로 수행
    • atexit 함수를 호출하여 Process 종료 시 호출할 함수들을 등록 가능하다.
  2. stdio의 모든 내용을 모두 flush
  3. 모든 temporal file들 삭제(tmpfile());
  4. _exit(2) 호출 : 이후 종료 과정은 kernel이 수행.
    • 사용 중이던 file descriptor들 닫기
    • 부모 프로세스에 exit status 전달
    • 부모 프로세스에게 SIGCHLD signal 전달
    • 자식 프로세스에게 SIGHUP signal 전달
    • Process가 사용하던 자원들 반납

다중 프로그램 시스템

여러개의 프로세스들이 존재. 프로세스들은 서로 독립적으로 동작. 공유 자원 또는 데이터가 있을 떄, 문제 발생 가능

동기화

프로세스 들이 서로 동작/정보/순서를 맞추는것

Zombie process / state

종료 되었지만, 아직 삭제되지 않은 프로세스
부모 프로세스보다 먼저 종료된 경우, zombie state가 됨

  • 자원 등은 모두 반납
  • 하지만 kernel에 최소한의 정보가 남아 있음(ex: exit status)

부모 프로세스가 exit status를 얻어 갈 때까지 zombie process로 남아 있는다. -> 결정적 이유

자식 프로세스 종료 상태 가져오기

#include <sys/typees.h>
#include <sys/wait.h>
pid_t wait(int *status);

자식 process가 종료 할 떄까지 대기. Child process가 종료 하면 exit status를 얻어 옴
child process가 여러 개인 경우, 그 중 하나 가장 빨리 종료 된 것의 exit status를 얻어 옴
Return = -1 : 실행 중인 자식이 없음

status 값 구조

  • [8bit(Exit으로 전달한 값)][Procedss를 종료 시킨 signal #]
  • [비정상 종료 시 = 0][정상 종료 시 = 0]
  • System 마다 다를 수 있음
  • Macro function 사용 할 것
  • WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status)

Ex

int main(void) {
  pid_t pid;
  
  switch (pid = fork()) {
    case -1:
      // error
      break;
    case 0: // child process handling
      printf("pid:%d, ppid:%d\n", (int)getpid(), (int)getppid());
      exit(2);
      break;
    default: // parent process handling
      int status;
      while (wait(&status) != pid)
        continue;
      printf("status(%d, %x)\n", status, status);
      printf("child process exit status : %d\n", WEXITSTATUS(status));
      break;      
  }
  return 0;
}

특정 pid를 지정할 수 있는 API도 제공한다

#include <sys/typees.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);

pid : 대상 process의 pid

  • < -1 : -pid => PGID로 해석하여 특정 PGID를 가지는 process
  • = 0 : Child process중 자식과 같은 PGID를 가지는 process중 하나
  • = -1 : Child process들 중 하나
  • > 0 : 특정 child process의 pid

option

  • WNOHANG : 자식이 종료하기 전이라도, 상태 값 바로 반환. 대기하지 않고 수행을 계속 함
    • NONBLOCK이기에 네트워크 소켓 사용 하는 것 처럼 폴링 방식으로 사용
  • WNOWAIT : 상태 값을 반환한 child process를 대기 상태로 유지. 다시 exit status를 요청 할 수 있음
profile
mohadang
post-custom-banner

0개의 댓글