프로세스 생성

새로운 프로세스 생성 목적

  1. 동일한 프로그램 처리를 여러 프로세스에 나눠서 처리 - fork()
  2. 다른 프로그램 생성 - fork(), execve()

프로세스 생성 방법

  1. fork() : 같은 프로세스를 두 개로 분열
  • 부모 프로세스가 fork() 함수 호출
  • 자식 프로세스용 메모리 영역 확보한 후, 그곳에 부모 프로세스의 메모리 복사
  • 부모와 자식은 모두 fork() 함수에서 복귀. 각각 fork() 함수 반환값이 달라서 분기 처리 가능
#!/usr/bin/python3

import os, sys

ret = os.fork() # 부모 프로세스면 자식의 pid를, 자식 프로세스면 0을 반환함

if ret == 0:
  print("child process id: {}, parent process id: {}".format(os.getpid(), os.getppid())) # ppid: 부모의 pid 값
  exit()

elif ret > 0 :
  print("parent process id: {}, child process id: {}".format(os.getpid(), ret)) # 여기서 자식 프로세스를 생성함
  exit()

sys.exit(1)
  1. execve()
  • execve() 함수 호출하면
  • 커널이 실행 파일을 읽고, 프로세스 메모리를 치환
  • 새로운 프로세스 시작
#!/usr/bin/python3

import os, sys

ret = os.fork()

if ret == 0:
  print("child process pid: {}, parent process pid: {}".format(os.getpid(), os.getppid()))
  os.execve("/bin/echo", ["echo", "{} say hello".format(os.getpid())], {}) # execve 프로세스 시작
  exit()

elif ret > 0:
  print("parent process pid: {}, child process pid: {}".format(os.getpid(), ret))
  exit()

sys.exit(1)

프로세스 상태

  • ps aux

  • 시스템에서 동작하는 프로세스를 기동한 시각 : START

  • 사용한 CPU 시간 합계 : TIME

  • 프로세스 상태 : STAT (Sleep,

  • (S) sleep 슬립 상태 : 각 프로세스는 실행 후 이벤트 발생 전까지 CPU 를 사용하지 않음 (ex, bash)

  • (R) runnable 실행 가능 상태 : CPU 를 사용하고 싶어하는 프로세스

  • running 실행 상태 : 실제로 CPU 를 사용하는 상태

  • (Z) zombie 좀비 상태 : 프로세스 종료 ~ 소멸 사이의 상태

  • 모든 프로세스가 슬립 상태면, 논리 CPU에서는 idle 프로세스 (아무 일도 하지 않는 프로세스) 동작

    • 노트북이나 휴대폰이 아무 동작 없이 배터리 오래가는 것 : 논리 CPU 의 idle 상태인 시간이 길어서 소비 전력 줄어들기 때문

프로세스 종료

  • 프로세스 종료하려면 exit_group() 이라는 시스템 콜 호출
    • python 의 exit() 함수 내부에서 해당 시스템 콜 호출함
  • 프로그램 종료 시, 커널이 프로세스 메모리 회수

좀비 프로세스와 고아 프로세스

  • 부모 프로세스는 wait() 계열 시스템 콜로 자식 프로세스 상태를 얻을 수 있음
    • 자식 프로세스는 죽었는데, 존재는 함 -> 좀비 프로세스
  • 불필요한 자원 낭비 없도록 부모는 자식을 제때 회수해서 커널로 보내야 함.
  • 시스템 기동했는데 좀비 프로세스가 많으면 버그 의심
  • wait() 계열 시스템 콜 없이 부모가 종료되면 자식은 고아 프로세스가 됨
    • 커널은 init을 고아 프로세스의 새로운 부모로 지정
    • 좀비 프로세스의 부모가 종료되면 init에 좀비 프로세스가 붙음
    • init은 정기적으로 wait() 계열 시스템 콜을 해서 시스템 자원 회수

시그널

  • 어떤 프로세스가 다른 프로세스에 신호를 보내서 - 외부에서 실행 순서를 강제로 바꾸는 방법
  • man 7 signal 로 확인
  • 종류
    • SIGINT : 곧바로 종료 bash에서 Ctrl + C, kill -INT pid.
    • SIGCHLD : 자식 프로세스 종료 시, 부모로 보내느 시그널. 시그널 핸들러 내부에서 wait() 계열 시스템 콜 호출
    • SIGSTOP : 프로세스 실행을 일시 정지. bash에서 Ctrl + Z 하면, bash에서 프로세스로 이 시그널 보냄
    • SIGCONT : SIGSTOP 등으로 정지된 프로세스 재개
    • SIGKILL : 최후의 수단. 반드시 죽임
      • 이걸로도 안죽는 프로세스는 uninterruptible sleep (D로 출력) 상태나 그 외 커널 문제.. 등 있음
  • 프로세스는 각 시그널에 시그널 핸들러를 미리 등록해둠
    • 프로세스 실행 중, 해당 시그널 수신 시, 실행 중인 처리 중단하고, 시그널 핸들러에 등록된 처리 동작 후, 이전 동작 재개
    • 시그널 무시 설정도 가능
#!/usr/bin/python3

import signal

# SIGINT 시그널이 들어오면 수행할 시그널 핸들러로 SIG_IGN 지정 
signal.signal(signal.SIGINT, signal.SIG_IGN)

whild True:
  pass
  
# Ctrl C 해도 안 멈춤

셀 작업 관리 구현

작업

  • bash와 같은 셸이 백그라운드로 실행한 프로세스를 제어하는 동작 구조

세션

  • 사용자가 gterm 과 같은 단말 에뮬레이터 또는 ssh 로 시스템 로그인 시, 로그인 세션과 같은 개념
  • 모든 세션에는 세션을 제어하는 단말 존재
  • pty/<n> 라는 가상의 단말이 각 세션에 할당됨
  • 세션ID (SID) 값이 할당됨.
  • 세션 리더라는 프로세스 존재 (ex, bash)
  • ps ajx 로 세션 관련 정보 확인
    • TTY : 세션의 가상 단말 이름
  • 세션에 할당된 단말이 행업, 단말 에뮬레이터 창 닫음 등의 이유로 연결 끊기면,
    • 세션 리더에 SIGHUP 시그널 보내짐
    • bash는 자신이 관리하던 작업 종료시키고 자신도 종료.
    • 계속 실행하려면 nohup (SIGHUP 무시하도록 설정하고 프로세스 기동), disown (실행 중인 작업을 bash 관리 대상에서 제외)

프로세스 그룹

  • 여러 프로세스를 하나로 묶어서 관리. 세션 내부에 여러 프로세스 그룹 존재.
  • PGID : 프로세스 그룹 고유 ID. ps ajx 의 PGID 항목
    • STAT에 + 붙은 프로세스는 포그라운드 프로세스 그룹에 속한 프로세스
  • 셸로 만든 작업이 프로세스 그룹이라고 생각. ex, 파이프로 연결된 프로세스
  • 셸은 프로세스 그룹에 소속된 모든 프로세스에 시그널 보내며 작업 제어.
  • kill -100 : PGID가 100인 프로세스 그룹에 시그널 보냄
  • 포그라운드 프로세스 그룹 : 셸의 포그라운드 작업에 대응. 세션당 하나만 존재. 세션 단말에 직접 접근 가능
  • 백그라운드 프로세스 그룹 : 셸의 백그라운드 작업에 대응. 백그라운드 프로세스가 단말 조작 시, SIGSTOP 처럼 실행이 일시 중단. fg 내장 명령어 등으로 프로세스가 포그라운드 프로세스 그룹 또는 포그라운드 작업 될 때까지 상태 유지.

데몬

  • 상주하는 프로세스.
  • 시스템 시작부터 종료까지 계속해서 존재하며 실행
  • 특징 (만족하지 않아도 상주 프로그램이면 편의상 데몬이라 함)
    • 단말 입출력이 필요 없으므로 단말이 할당되지 않음
    • 로그인 세션을 종료해도 영향을 받지 않도록 독자적인 세션 존재
    • 데몬을 생성한 프로세스가 데몬 종료 여부를 신경쓸 필요 없이 init이 부모가 됨.
  • ps ajx
    • sshd (ssh 서버로 동작하는 데몬) : 부모 프로세스가 init (PPID = 1) 이고, 세션 ID (SID)와 PID가 동일, TTY 가 단말과 연결되지 않음을 뜻하는 ?
  • 데몬은 단말이 없으므로 단말의 행업을 뜻하는 SIGHUP을 다른 용도로 사용
    • 일반적으로 데몬이 설정 파일을 다시 읽는 시그널로 사용
profile
노션에 1차 정리합니당 - https://cream-efraasia-f3c.notion.site/4fb02c0dc82e48358e67c61b7ce8ab36?v=

0개의 댓글

Powered by GraphCDN, the GraphQL CDN