/*
 http://sosal.tistory.com/
 * made by so_Sal
 */


system() 함수에 대해 알아보겠습니다.

#include<stdlib.h>
int system(const char * string)

system() 함수는 굉장한 편리함을 가져다 주는 함수입니다.
어떻게 보면 게으른 사람들의 전유물이기도 하지요..

shell? :: 사용자가 입력하는 명령어들을 기계어로 번역해주는 명령 해석기
쉘은 사용자가 운영체제와 대화할 수 있는 중간 역할자. 인터페이스가 됩니다.
쉘에서 사용자가 한 말을 받아 운영체제에 전해주고, 운영체제는 그 답을 쉘을 통해서
사용자에게 보여주게 되는것입니다. 쉘 역시 하나의 프로그램입니다.
(bash, sh, csh 등 다양한 종류의 쉘이 있는데..
 리눅스 콘솔창에서 우리가 명령어 치는게 쉘입니다.)

Linux 구조
User       - 사용자
shell       - 사용자가 명령어를 입력하는곳
utility
kernel           // 사용자가 명령어를 입력하면 아래로 내려가서
hardware      // 명령수행을 끝낸 후 다시 올라옵니다.

위 구조에서 볼 수 있듯, user와 시스템 사이에 shell이 존재하여
utility,kernel,hardware등 접근 할 수 있게 됩니다.

그럼 pstree를 입력해볼까요?
(프로세스 부모. 자식관계 목록 호출)
저는 putty를 이용하여
ssh로 접속하였기 때문에
ssh를 가능하게 해주는 sshd라는 프로세스를 통하여 bash가 실행되어 있습니다.
자신의 bash의 위치를 찾아서 뒤에 pstree가 켜져있는것을 보시면..
pstree는 사용자의 쉘(bash) 상태에서 새로이 켜진 프로세스이기 때문에
bash의 자식으로 표현됩니다.

그럼 이제 자식프로세스를 생성하는 system() 함수 프로그램 예제를 봅시당.

이 소스의 이름은 system.c 입니다.

#include<stdio.h>
#include<stdlib.h>
// system()함수가 들어있는 헤더
                           // 이 헤더파일은 exit() //프로세스 종료, fork() //자식프로세스 생성 등
                           // 프로세스에 관련된 함수들을 다루는 헤더파일입니다.

int main(void){
  system("pstree"); // pstree를 실행하는 코드
  exit(0);
}

굉장히 간단한 코드입니다. 컴파일 후 실행시켜 볼까요?
sosal@ ~] $ gcc system.c -o system
sosal@ ~] $ ./system

bash 이후에 system을 실행시켰으니 내 bash 아래에 system이란 프로세스가
올라왔군요.. 그리고 system이란 프로세스는 system()함수를 이용하여
pstree를 실행 시켰기 때문에 또 자식이 생기네요.

아 ! 여기서 system()함수는 pstree라는 자식프로세스를 만드는것이군요!
라고 깨닳을 수 있겠습니다.!!


system()함수의 고찰
부모 프로세스는 (system() 를 호출시키려는 원래의 프로그램)
system()함수로 호출된 새로운 자식 프로세스의 모든 행동이
끝날때 까지 (프로세스가 완전히 종료될 때 까지)
계속 기다리게 됩니다.


제가 system()함수에 대해서 게으른 사람들의 전유물이라고 언급을 했었는데,
그 말에 대해서 이야기 해봅니다.

사실 system()함수는 2개의 함수로 이루어져있습니다.
프로세스는 원하는 새로운 프로세스를 아무렇게나 생성할 수 있는 능력이 없습니다.
하지만, 하나의 방법을 가지고 있는데
자신과 똑같이 생긴녀석을 자식으로 생성하는것입니다.
이 역할을 하는것이 fork() 함수입니다.
(fork함수에 대한 자세한 내용은 system 관련글을 참조하세요.)

하지만 이방법으로는 프로세스가 원하는 다른 프로세스를 키는 방법이 없겠군요..
볼품없는 자신과 똑같은 녀석들만 자식으로 밑에 딸려버리니..

하지만 자식들이 변신을 시도한다면?
자신과 똑같은 자식을 낳고, 부모가 원하는데로 변신하도록 하게 한다면?
부모 프로세스는 기쁘겠지요. 그 역할은 exec 계열 함수입니다.
(사실 exec라는 함수는 없습니다. execl, execlp, execve 등 함수가 존재, 다음 글에서 설명)

system 함수는 위 함수들을 이용하여 구성되어집니다.
fork함수를 이용하여 자식프로세스를 만든 후
자식프로세스를 exec 함수로 다른 프로그램으로 바꿔버리는 것입니다.

위 예제에서는 system이란 파일이 자신과 똑같은 system이란 자식을 만든 후
pstree라는 프로그램으로 바꿔버리는것이죠..

system함수의 원리 동작만 이해한다면
fork함수와 exec계열 함수 아무 문제 없습니다.

**하지만 system()함수가 fork() + exec()인것은 아닙니다.
차이점이 있는데, system함수는 호출했을때 생기는 자식프로세스에 제어권이 가는것,
부모 프로세스는 실행을 멈추는것. 이라는 가장 큰 차이점이 있습니다.

이제 당신은 다중 프로세스 프로그래밍이 가능한 리눅스 프로그래머!!

System 게시물들은
begining Linux programing.
유닉스 프로그래밍
Linux 언쉬리드' 를 참고하였습니다.
Posted by sosal sosal

댓글을 달아 주세요

  1. 2009.10.26 13:27

    글 잘봤습니다~
    리눅스에는 윈도우 API의 CreateProcess 와 일치하는 기능은 없은건가요??
    궁금합니다 ㅎㅎ

    • 2010.01.05 18:46 신고

      이 글의 system함수는 프로세스 내에서
      잠깐 다른 프로세스로 제어권을 넘기는거에요.
      새로운 프로세스를 띄운다기 보다는 제어하고있는 한 프로세스를 멈추고 잠깐 다른 프로세스를 깔짝대다가 끝나구 다시 돌아오는거에요.
      윈도우 CreateProcess는 완전히 새로운
      자식프로세스를 띄우는건데
      system()과는 많이 다르죠.

      리눅스에서는 fork함수와 exec계열 함수를
      이용하여 CreateProcess와 같은 결과를
      만들 수 있습니다

      fork함수는 리눅스에서 새로운 프로세스를 생성하는 유일한 함수입니다. 현재 프로세스와 똑같은 프로세스를 복사하는거에요.
      복사된 프로세스는 자식프로세스라 하는데
      그 자식프로세스에게 exec 계열 함수를(프로세스를 바꿔버림)호출하게 하면 결과적으로 CreateProcess와 같은 결과 (원하는 새 프로세스를 띄움)를 얻을 수 있습니다. ^-^

      exec 계열 함수와 fork 함수에 대한 글을 보시면
      쉽게 사용하실 수 있습니다 ^^