본문 바로가기

카테고리 없음

[시스템프로그래밍] 프로세스, ps, shell, execvp(), fork()

목차

  • 유닉스 쉘이 하는 일
  • 유닉스의 프로세스 모델
  • 프로그램을 실행하는 법
  • 프로세스를 어떻게 만드는가
  • 부모와 자식 프로세스간 통신하는 법
  • 시스템콜
    • fork
    • exec
    • wait
    • exit
  • command
    • sh
    • ps

Program과 Process

  • program: 기계어 명령어와 데이터 덩어리 => 파일, 데이터의 의미
  • process: 프로그램이 실행되고 있는 메모리 공간과 환경 => processes are programs in action
  • running a program: 프로그램의 명령어들을 메모리에 적재하고, 프로세서(CPU)가 하나씩 실행함

Command

ps

현재 process들을 나열

  • PID : process ID
  • TTY : terminal type, 유저가 로그인하고 있는 콘솔 또는 터미널의 이름(ex: pts/5)
  • TIME : CPU time
  • CMD

ps -la

  • S : status
    • S : sleeping (일시 중단)
    • R : running
  • UID : 누가 이 process를 실행시키는가
  • PPID : parent process ID

Computer Memory & Computer Program

- 유닉스 시스템에서 메모리는 커널 영역과 유저 영역으로 나뉨

- 프로세스는 유저 영역에 있음, 커널 영역을 침범해선 안됨

- 프로세스는 디스크 파일로서 메모리에 디스크 블록(pages)으로 나뉘어 저장되어 있음

The shell

  • shell

shell = program launcher

프로그램을 메모리에 적재하고 실행시킬 수 있다.

 

  • -bash

리눅스에서는 기본 -bash 쉘을 사용한다

  • sshd

쉘을 실행시켜주는 쉘 데몬

계속 백그라운드에서 동작함(쉘을 실행시켜주기 위해 항상 대기 중)

모든 프로세스의 부모 프로세스, 제거하면 다 종료됨

Shell의 프로그램 실행 원리

  1. user가 a.out을 타이핑한다 (input)
  2. shell은 프로그램을 실행시킬 new process를 생성한다
  3. shell은 디스크에 저장된 프로그램(파일)을 찾아 프로세스(새로운 공간)에 적재한다
    • $ which ls : 파일 위치 알려줌
    • /usr/bin/ls : ls 프로그램이 저장된 위치

프로그램은 그 프로세스 안에서 실행된다

어떻게 실행하는가? => execvp() 시스템콜

execvp(proname, arglist)

명령어에 대한 실행결과를 알려주는 거, shell처럼 동작하는 명령어

 

main() {
	char *arglist[3];
    arglist[0] = "ls";
    arglist[1] = "-l";
    arglist[2] = "0";
    printf("* * * About to exec ls -l\n");
    execvp("ls" arglist);
    printf("* * * ls is done. bye\n");      // 출력되지 않음
   }

 

왜 두 번째 printf문은 출력되지 않을까?

execvp는 command(process)를 만나면 그 프로세스로 변하기 때문에. 실행 후 exit.
해결법: 새로운 프로세스가 필요함 => fork() 시스템콜을 사용하여 현재 프로세스를 복제함

 

새로운 command를 만나면 그 프로세스를 실행 후 exit

fork()

원래 프로세스를 새로운 프로세스에 완전히 복제

새로운 프로세스는 fork() 이후부터 실행함