Linux system programming
This presentation is the property of its rightful owner.
Sponsored Links
1 / 66

Linux System Programming PowerPoint PPT Presentation


  • 147 Views
  • Uploaded on
  • Presentation posted in: General

Linux System Programming. Lecture #6 – 프로세스 생성과 수행. 프로세스의 소개 (1). 프로세스의 정의 : 프로세스 (Process) 란 실행중인 프로그램을 의미 예 : 파워포인터 프로그램을 실행하였을 경우 - (1) 하드디스크에 설치되어 있는 프로그램 - 저장된 프로그램 (2) 실행하기 위해 메모리에 로딩된 프로그램 - 프로세스 프로세스는 운영체제가 서비스를 제공하는 대상

Download Presentation

Linux System Programming

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Linux system programming

Linux System Programming

Lecture #6

–프로세스 생성과 수행


Linux system programming

프로세스의 소개 (1)

  • 프로세스의 정의:

    • 프로세스(Process)란 실행중인 프로그램을 의미

      • 예: 파워포인터 프로그램을 실행하였을 경우 -

        (1) 하드디스크에 설치되어 있는 프로그램 - 저장된 프로그램

        (2) 실행하기 위해 메모리에 로딩된 프로그램 - 프로세스

    • 프로세스는 운영체제가 서비스를 제공하는 대상

      • 사용자가 하나의 프로그램을 실행하면 운영체제는 그 프로그램을 실행하는 하나의 프로세스를 생성하고, 프로세스가 프로그램을 실행하기 위해 요구하는 서비스를 제공한다

      • Multitasking을 지원하는 운영체제는 동시에 한 개 이상의 프로세스를 생성할 수 있으며, 이들 프로세스가 동시에 동작하도록 서비스를 제공한다

    • 동일한 프로그램에 대해 여러 개의 프로세스가 생성될 수 있다

      • 예: 동시에 파워포인터 프로그램을 2개 이상 실행한 경우

    • 프로세스는 상호 독립적으로 동작한다

Linux System Programming


Linux system programming

프로세스의 소개 (2)

  • 프로세스의 정의:

    • Linux 운영체제에서 프로세스간에 계층 구조를 갖는다

      • Linux 운영체제에서는 fork 시스템 호출에 의하여 프로세스를 생성

      • 프로세스 0을 제외한 모든 프로세스는 다른 프로세스가 fork 시스템 호출을 수행하여 만들어진다.

      • fork를 호출한 프로세스를 부모 프로세스라 하고, 새로 만들어진 프로세스를 자식 프로세스라 한다.

      • 모든 프로세스는 오직 하나의 부모 프로세스를 가질 수 있지만, 자식 프로세스는 여러 개를 가질 수 있다.

Linux System Programming


Linux system programming

프로세스의 소개 (3)

  • 프로세스의 정의:

    • Linux 커널은 각 프로세스들을 프로세스 ID(정수값)로 구분한다

    • 프로세스 0은 시스템이 부트될 때 만들어지며, 프로세스 1을 fork한 후에는 스와퍼(swapper)가 된다

    • 프로세스 1은 init 프로세스라고 알려져 있는데, 시스템 내의 다른 모든 프로세스의 조상이 된다

Linux System Programming


Linux system programming

프로세스의 소개 (4)

  • 프로세스의 구조:

    • 실행 가능 파일(Executable File)

      • 원시 코드 파일을 컴파일하여 생성되는 파일

      • 구조:

      • 프로그램 텍스트 –원시 코드를 컴파일하여 생성된 기계어 코드

      • 데이터 영역 –원시 프로그램에서 정의된 전역 변수 및 상수에 대한 정보를 저장

Linux System Programming


Linux system programming

프로세스의 소개 (5)

  • 프로세스의 구조:

    • 실행 가능 프로그램이 주기억 장치로 적재(load)되어 프로세스가 생성되면 텍스트 영역과 액티베이션(activation) 레코드로 구분되어 존재

    • 액티베이션 레코드는 전역(global) 데이터 영역과 스택 영역으로 이루어져 있으며, 전역 데이터 영역은 초기화 데이터와 비초기화 데이터 영역으로 구성

    • 초기화 데이터 영역은 프로그램에서 초기화가 배정된 변수, 배열이나 구조체(structure) 등이 저장되며, 비초기화 데이터 영역에는 초기값을 배정하지 않은 변수, 배열, 구조체 등의 기억 장소이다.

Linux System Programming


Linux system programming

프로세스의 소개 (6)

  • 프로세스의 구조:

    • 운영 체제의 가상 공간에는 커널 프로그램이 저장된 텍스트(text) 영역과 시스템에서 수행중인 프로세스들을 관리하기 위한 프로세스 테이블들이 저장된 데이터 영역으로 구분

    • 커널 공간에 프로세스 생성과 관련된 데이터 구조:

      (1) 프로세스 테이블

      (2) PCB(프로세스 제어 블록)

      (3) 사용자 영역(u-area) –파일 디스크립터 테이블, OS 스택 등

Linux System Programming


Linux system programming

프로세스의 소개 (7)

  • 프로세스의 구조:

Linux System Programming


Linux system programming

프로세스의 소개 (8)

  • 프로세스의 상태:

    • 프로세스 문맥(Process Context)은 프로세스의 현재 상태를 의미

    • 프로세스 문맥은 프로세스의 텍스트, 전역 사용자 변수들과 데이터 구조들의 값, 프로세스가 사용하는 기계 레지스터의 값, 프로세스 테이블 항과 user area에 저장된 값들, 사용자 스택과 커널 스택의 내용 등에 의해 정의된다.

    • 하나의 프로세스가 실행되고 있을 때, 시스템은 그 프로세스 문맥에서 실행 중이라고 정의

      • 현재 CPU가 접근하는 메모리 영역을 의미

    • 현재 실행중인 프로세스를 중지하고 새로운 프로세스를 실행하기 위해서는 문맥 교환(Context Switching)이 이루어진다

    • 실행 중인 프로세스가 시스템 호출을 요청하면 시스템은 사용자 모드에 커널 모드로 변환하여 실행중인 프로세스 문맥에서 커널 프로그램을 실행한다(모드 변환)

Linux System Programming


Linux system programming

프로세스의 소개 (9)

  • 프로세스의 상태:

Linux System Programming


Linux system programming

프로세스의 소개 (10)

  • 예제 6-1:

    • 프로세스 이미지에 대한 텍스트(etext), 데이터(edata), 스택 및 사용자 영역의 한계점(end point)을 출력해 준다.

#define PRADDR(X) printf(" X at %o and value = %o\n",&X,X)

extern etext, edata, end;

static char s = 'S';

int a,b = 1;

main(int argc,char *argv[])

{

void sub1();

static int c, d =1;

char m,n = 'n';

printf("main at %o and sub1 at %o\n",main,sub1);

printf("end of text segment at %o\n",&etext);

PRADDR(s); PRADDR(b);

PRADDR(c); PRADDR(d);

Linux System Programming


Linux system programming

프로세스의 소개 (11)

printf("end of statics & initialized externals at %o\n", &edata);

PRADDR(a);

printf("end of uninitialized externals at %o\n", &end);

PRADDR(m); PRADDR(n);

PRADDR(argc); PRADDR(argv);

for(b = 0; b<argc; b++)

printf("argv[%d] at %o and value = %o or %s\n",

b, &argv[b], argv[b], argv[b]);

sub1(c);

}

void sub1(int p)

{

static int t;

char v;

PRADDR(t); PRADDR(p); PRADDR(v);

}

Linux System Programming


Linux system programming

프로세스의 크기 변경 (1)

  • 프로세스의 크기 변경:brk, sbrk

Linux System Programming


Linux system programming

프로세스의 크기 변경 (2)

  • 프로세스의 크기 변경:brk, sbrk

Linux System Programming


Linux system programming

프로세스의 크기 변경 (3)

  • 예제 6-4:

    • brk와 sbrk 시스템 호출을 이용하여 수행중인 프로세스의 크기를 설정하고 출력하는 프로그램을 작성하라.

extern int etext, edata, end;

main()

{int brk(), ret;

char *sbrk(), *bv;

system("clear");

printf("The program text ends at %07o\n", &etext);

printf("The initialized data ends at %07o\n", &edata);

printf("The uninitialized data ends at %07o\n", &end);

bv = sbrk(0);

printf("Current break value is %07o\n\n",bv);

ret = brk(bv+512); /* 01000 */

printf("brk returned . . . . %d\n",ret);

bv = sbrk(0);

printf("Current break value is %07o\n\n",bv);

Linux System Programming


Linux system programming

프로세스의 크기 변경 (4)

ret = brk(&ret);

printf("brk returned . . . . %d\n",ret);

bv = sbrk(0);

printf("Current break value is %07o\n\n",bv);

bv = sbrk(64); /* 0100 */

printf("sbrk returned %07o\n",bv);

bv = sbrk(0);

printf("Current break value is %07o\n\n",bv);

bv = sbrk(-1024); /* memory deallocation: -02000 */

printf("sbrk returned %07o\n",bv);

printf("Current break value is %07o\n\n",bv);

}

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (1)

  • 프로세스의 사용자 식별(ID): setuid, setgid

    • 실제 사용자 ID(Real User ID)는 수행 중인 프로세스에 대해 책임을 지닌 사용자 ID

    • 유효 사용자 ID(Effective User ID)는 다음의 작업에 적용

      • 새로 만들어진 화일의 소유권을 지정

      • 화일 접근 허가를 검사

      • kill 시스템 호출에 의해 프로세스들에게 신호를 보낼 수 있는 허가를 검사

    • 커널은 프로세스가 setuid 프로그램을 실행(exec)하거나, setuid 시스템 호출을 통하여 프로세스의 유효 사용자 ID를 변경하도록 허용한다.

      • setuid 프로그램이란 허가 모드 필드의 setuid 비트가 1로 세트되어 있는 실행 가능 파일

      • 프로세스가 setuid 프로그램을 실행(exec)하면, 커널은 프로세스 테이블과 u area 상의 유효 사용자 ID와 필드를 화일의 소유자 ID로 세트한다

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (2)

  • 프로세스의 사용자 식별(ID):setuid, setgid

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (3)

  • 예제 6-2:

    • 아래의 조건에 따라 읽기 전용 파일을 생성하는 프로그램을 작성하고 실사용자와 유효 사용자의 관계를 확인하라. 1. 실사용자와 유효 사용자의 ID를 출력한다. 2. fopen() 함수를 사용하여 파일 접근의 성공과 실패를 검사한다. 3. setuid 함수를 이용하여 실사용자와 유효 사용자가 동일하게 만든다. 4. 1-2를 반복한다.

    • 실험은 다음 단계로 한다. 1. 프로그램을 실행하고 출력을 관측한다. 2. 그룹 멤버가 프로그램을 수행할 수 있도록 접근 허가를 수정하여 그룹 멤버로 하여금 프로그램을 수행시킨다. 3. set-user-id 비트를 설정하고 그룹 멤버로 하여금 프로그램을 수행시킨다.

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (4)

#include <stdio.h>

main(int argc, char *argv[])

{

FILE *fp ;

char line[256];

int uid;

if(argc <2) {

fprintf(stderr,"Usage: %s file_name\n",argv[0]);

exit(1);

}

printf("initially uid=%d and euid%d\n",getuid(), geteuid());

fp = fopen(argv[1],"r");

if(fp = NULL) {

fprintf(stderr,"first open of %s failed",argv[1]);

exit(2);

}

else {

printf("first open successful:\n");

while(fgets(fp,line,255)!=NULL)

fputs(stdout,line);

fclose(fp);

}

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (5)

setuid(uid = getuid());

printf("after setuid(%d):\n uid=%d and euid=%d\n",uid, getuid(), geteuid());

fp = fopen(argv[1], "r");

if(fp == NULL) {

fprintf(stderr,"second open of %s failed",argv[1]);

exit(3);

}

else {

printf("second open successful:\n");

while(fgets(line,255,fp) != NULL)

fputs(line,stdout);

fclose(fp);

}

}

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (6)

  • 예제 6-3:

    • 아래 주어진 옵션(option)에 따라 프로세스의 정보를 출력하는 프로그램을 작성하라. 옵션(option)의 분해에는 getopt함수를 사용한다.

    • -i:사용자(user)와 그룹(group)의 실사용자 및 유효 사용자 ID를 다음의 함수를 사용하여 출력한다.

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (7)

  • 예제 6-3:

    • -s:setpgrp() 함수를 이용하여 프로세스를 새로운 그룹에 포함시킨다

    • -p:프로세스, 부모 프로세스, 그룹 프로세스 ID를 다음 함수를 이용하여 출력한다.

    • -u: ulimit() 함수를 호출하여 프로세스의 크기에 대한 값을 출력한다.

    • -Unewlimit: ulimit() 함수를 이용하여 프로세스 크기에 대한 값을 새로 설정한다.

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (8)

#include <stdio.h>

#define GET_FSLIM1

#define SET_FSLIM2

extern char*optarg;

extern intoptind;

main(int argc, char *argv[])

{

intgetopt(), c;

long ulimit(), atol();

static char options[] = "ispuU:";

if(argc < 2)

fprintf(stderr,"Usage: %s [-i] [-s] [-p] [-u] [-Unewulimit]\n",argv[0]);

while((c=getopt(argc,argv,options)) != EOF)

switch(c) {

case 'i':

printf("real userid = %d\n",getuid());

printf("effective userid = %d\n",geteuid());

printf("real groupid = %d\n",getgid());

printf("effective groupid = %d\n",getegid());

break;

Linux System Programming


Linux system programming

프로세스의 사용자 식별 (9)

case 's':

(void) setpgrp();

break;

case 'p':

printf("process number = %d\n",getpid());

printf("parent process number = %d\n",getppid());

printf("group process number = %d\n",getpgrp());

case 'U':

if(ulimit(SET_FSLIM,atol(optarg)) == -1)

fprintf(stderr,"Must be super-user to increase ulimit\n");

break;

case 'u':

printf("ulimit = %ld\n",ulimit(GET_FSLIM,0L));

break;

}

}

Linux System Programming


Linux system programming

프로세스의 환경변수 (1)

  • 프로세스의 환경 변수:getenv, putenv

    • LINUX 프로세스의 환경은 셸(shell) 변수들로써 이루어져 있다.

    • 셸(shell) 변수들은 스택(stack)에 저장되어 있고 그들을 접근하는 가장 간단한 방법은 명령어 행의 인수(argument)들을 접근하는 것처럼 주함수(main function)에 파라미터를 하나 더 추가하는 것이다.

    • 전역 변수 envion은 환경 변수들이 저장된 테이블의 시작 주소를 가지고 있다. 그러므로 프로그램에서 다음과 같이 선언하여 환경 변수에 접근할 수 있다.

Linux System Programming


Linux system programming

프로세스의 환경변수 (2)

  • 프로세스의 환경 변수:getenv, putenv

Linux System Programming


Linux system programming

프로세스의 환경변수 (3)

  • 예제 6-5:

    • 자신의 환경 변수들을 모두 출력하는 프로그램을 작성하라.

    • 환경 변수 TZ(Time Zone)을 변경한 후 변경된 내용을 출력하여 확인하라.

    • 새로운 환경 변수 WARNING에 값을 설정한 후 그 내용을 출력시켜라.

Linux System Programming


Linux system programming

프로세스의 환경변수 (4)

extern char **environ;

void main(int argc, char *argv[], char *envp[])

{

char *getenv();

printenv("Initially", &envp);

putenv("TZ=PST8PDT");

printenv("After changing TZ", &envp);

putenv("WARNING=Don't use envp after putenv()");

printenv("After setting a new variable",&envp);

printf("value of WARNING is %s\n",getenv("WARNING"));

}

Linux System Programming


Linux system programming

프로세스의 환경변수 (5)

void printenv(char *label, char ***envpp)

{

char **p;

printf("---- %s ---\n",label);

printf(" envp is at %8o and contains %8o\n", envpp, *envpp);

printf("environ is at %8o and contains %8o\n", &environ, environ);

printf("My environment variables are:\n");

for(p=environ; *p; p++)

printf("(%8o) = %8o -> %s\n",p,*p,*p);

printf("(%8o) = %8o\n", p, *p);

}

Linux System Programming


Linux system programming

프로세스의 생성 (1)

  • 프로세스의 생성:fork

Linux System Programming


Linux system programming

프로세스의 생성 (2)

Linux System Programming


Linux system programming

프로세스의 생성 (3)

  • 프로세스의 생성:fork

    • 커널은 fork 수행시 다음과 같은 순서로 동작한다. 1. 새로운 프로세스를 위해 프로세스 테이블 항을 할당한다. 2. 자식 프로세스에게 고유의 ID 번호를 부여한다. 3. 부모 프로세스의 내용을 논리적으로 복사한다. 예를 들면, 텍스트 영역과 같은 프로세스의 일부 영역은 프로세스 사이에 공유될 수 있으므로, 커널은 그 영역을 메모리 내의 새로운 위치에 복사하는 대신 영역 참조 계수(region reference count)를 증가시킬 수도 있다. 4. 프로세스와 관련된 파일에 대해 파일 테이블과 inode 테이블 카운터(counter)를 증가시킨다. 5. 부모 프로세스에게는 자식의 ID 번호를 복귀시키고, 자식 프로세스에게는 0을 복귀시킨다.

Linux System Programming


Linux system programming

프로세스의 생성 (4)

Linux System Programming


Linux system programming

프로세스의 생성 (5)

  • 예제 6-6:

    • fork() 시스템 호출 전에 부모 프로세스의 ID를 출력하고 fork() 시스템 호출 후에 부모 및 자식 프로세스의 ID를 출력하여 fork 함수의 기능을 확인할 수 있는 프로그램을 작성하라.

    • 현재 수행중인 프로세스의 ID는 getpid() 함수를 사용하고, 현재 프로세스의 부모 프로세스 ID는 getppid() 함수를 사용하여 얻는다.

Linux System Programming


Linux system programming

프로세스의 생성 (6)

#include <stdio.h>

main()

{

int getpid(), getppid();

printf("[%d] parent process id: %d\n",getpid(), getppid());

fork();

printf("\n\t[%d] parent process id: %d\n",getpid(), getppid());

printf("THIS IS FORK SYSTEM CALL TEST.\n");

}

Linux System Programming


Linux system programming

프로세스의 생성 (7)

  • 예제 6-7:

    • 부모 프로세스는 대문자로 A에서 Z까지 출력하고 동시에 자식 프로세스는 소문자로 a에서 z까지 출력하는 프로그램을 작성하여 두 개의 프로세스가 동시에 수행되고 있음을 확인하라.

Linux System Programming


Linux system programming

프로세스의 생성 (8)

main(int argc, char *argv[])

{

char ch, first, last;

int pid;

long i;

if((pid = fork())>0) { /* parent */

first = 'A';

last = 'Z';

}

else if(pid == 0) { /* child */

first = 'a';

last = 'z';

}

else { /* not fork(2) */

perror(argv[0]);

exit(1);

}

printf("\n");

for(ch = first; ch <= last; ch++) {

/* delay loop */

for(i=0; i<= 100000; i++);

write(1, &ch, 1);

}

}

Linux System Programming


Linux system programming

다른 프로그램의 호출 (1)

  • 다른 프로그램의 호출:exec

Linux System Programming


Linux system programming

다른 프로그램의 호출 (2)

  • 다른 프로그램의 호출:exec

Linux System Programming


Linux system programming

다른 프로그램의 호출 (3)

  • 다른 프로그램의 호출:exec

Linux System Programming


Linux system programming

다른 프로그램의 호출 (4)

  • 다른 프로그램의 호출:exec

Linux System Programming


Linux system programming

다른 프로그램의 호출 (5)

  • 예제 6-8:

    • 다음 프로그램은 exec 시스템 호출에서 사용될 예제로써 명령어 라인에서 준 인수들과 셸(shell) 환경 변수들을 출력해 준다.

    • argv[] 값과 environ은 exec 시스템 호출시 매개 변수로서 사용될 것이다.

    • 프로그램을 수행시켜 결과를 분석하라.

Linux System Programming


Linux system programming

다른 프로그램의 호출 (6)

extern char **environ;

main(argc, argv) /* program to be exec(2)'ed */

int argc;

char *argv[];

{

char **p;

int n;

printf("My input parameters(argv) are: \n");

for(n=0; n < argc; n++)

printf(" %2d: '%s'\n", n, argv[n]);

printf("\nMy environment variables are:\n");

for(p= environ; *p !=(char *) 0; p++)

printf(" %s\n", *p);

}

Linux System Programming


Linux system programming

다른 프로그램의 호출 (7)

  • 예제 6-9:

    • execl 시스템 호출 함수를 사용하여 예제 프로그램 ex6-8을 실행시키는 프로그램을 작성하라.

    • execl은 argv 인수 리스트를 사용함을 참고하라.

#include <stdio.h>

main()

{

printf("this is the original program\n");

execl("./ex6-8","ex6-8","parm1","parm2","parm3",(char *) 0);

perror("This line should never get printed\n");

}

Linux System Programming


Linux system programming

다른 프로그램의 호출 (8)

  • 예제 6-10:

    • execv 시스템 호출 함수를 이용하여 예제 프로그램 ex6-8을 실행시키는 프로그램을 작성하라.

#include <stdio.h>

main()

{

static char *nargv[] = {

"ex6-8", "parm1", "parm2", "parm3", (char *) 0};

printf("this is the original porgram\n");

execv("./ex6-8",nargv);

perror("This line should never get printed\n");

}

Linux System Programming


Linux system programming

다른 프로그램의 호출 (9)

  • 예제 6-11:

    • execve 시스템 호출 함수를 이용하여 예제 프로그램 ex6-8을 실행시키는 프로그램을 작성하라.

#include <stdio.h>

main()

{

static char *nargv[] = {

"ex6-8", "parm1", "parm2", "parm3", (char *) 0};

static char *nenv[] = {

"NAME=value", "nextname=nextvalue", "HOME=/xyz", (char *) 0};

printf("this is the original porgram\n");

execve("./ex6-8",nargv,nenv);

perror("This line should never get printed\n");

}

Linux System Programming


Linux system programming

다른 프로그램의 호출 (10)

  • 예제 6-12:

    • execvp 시스템 호출 함수를 이용하여 예제 프로그램 ex6-8을 실행시키는 프로그램을 작성하라.

#include <stdio.h>

main()

{

static char *nargv[] = {

"ex6-8", "parm1", "parm2", "parm3", (char *) 0};

printf("this is the original porgram\n");

execvp("ex6-8",nargv);

perror("This line should never get printed\n");

}

Linux System Programming


Linux system programming

다른 프로그램의 호출 (11)

  • 예제 6-13:

    • exec 시스템 호출 함수를 이용하여 다른 프로그램을 실행시키면 본래의 프로그램은 실행이 중단되는 결과를 가져온다. 그러므로 프로그램에서 exec 함수를 이용하여 다른 프로그램을 수행시킨 후 중단없이 작업을 계속하려면 fork를 이용하여 자식 프로세스가 exec 함수를 호출하게 만들면 부모 프로세스의 중단없이 작업을 계속 수행할 수 있다.

    • fork와 exec 함수를 이용하여 부모 프로세스가 중단되지 않도록 exec 함수를 사용하여 LINUX의 echo 명령어를 실행시키는 프로그램을 작성하라.

Linux System Programming


Linux system programming

다른 프로그램의 호출 (12)

main()

{

int fork();

if(fork() == 0) {

execl("/bin/echo", "echo","this is","message one",(char *) 0);

perror("exec one failed");

exit(1);

}

if(fork() == 0) {

execl("/bin/echo","echo","this is","message two",(char *) 0);

perror("exec two failed");

exit(2);

}

if(fork() == 0) {

execl("/bin/echo","echo","this is","message three",(char *) 0);

perror("exec three failed");

exit(3);

}

printf("Parent program ending\n");

}

Linux System Programming


Linux system programming

프로세스 종료

  • 프로세스이 종료:exit

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (1)

  • 프로세스이 종료를 기다림: wait

    • wait는 자식 프로세스가 수행되고 있는 동안 부모 프로세스의 수행을 일시적으로 중단시킨다.

    • 자식 프로세스가 수행을 마치면, 기다리던 부모 프로세스는 수행을 재개한다.

    • 하나 이상의 자식 프로세스가 수행되고 있으면, wait는 자식프로세스들 중 하나가 최초로 종료되는 시간에 복귀된다.

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (2)

  • 프로세스이 종료를 기다림: wait

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (3)

  • 예제 6-14:

    • fork 시스템 호출 함수를 이용하여 자식(child) 프로세스를 생성하여 자식 프로세스 및 부모 프로세스의 ID를 출력하고 부모 프로세스에서는 wait 함수를 이용하여 자식 프로세스의 종료를 기다리는 프로그램을 작성하라.

    • 또한 wait 함수의 반환값(return value)과 자식 프로세스로부터 받을 상태값(status value)을 출력시켜라.

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (4)

#define EXIT_CODE 1

main(int argc, char *argv[])

{

int pid, ret, status, fork(), wait();

void exit();

if((pid = fork()) ==0) { /* child */

printf("child: pid=%d ppid=%d exit_code=%d\n",

getpid(), getppid(), EXIT_CODE);

exit(EXIT_CODE);

}

printf("parent: wating for child=%d\n", pid);

ret = wait(&status);

printf("parent: return value=%d, ",ret);

printf(" child's status=%x", status);

printf(" and shifted=%x\n", (status >> 8));

exit(0);

}

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (5)

  • 예제 6-15:

    • 부모 프로세스에서 두 개의 자식 프로세스를 생성하여 각각 execl 함수를 이용해서 echo 명령어를 수행시켜 메시지를 출력하고, 부모 프로세스는 이들 자식 프로세스들이 종료하기를 기다리는 프로그램을 작성하라.

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (6)

main(int argc, char*argv[])

{

int fork(), wait();

if(fork() == 0) /* child */

execl("/bin/echo","echo","this is","message one",(char *) 0);

if(fork() == 0) /* child */

execl("/bin/echo","echo","this is","message Two",(char *) 0);

printf("parent: wating for children\n");

while(wait((int *) 0) != -1) ; /* null */

printf("parent: all children terminated\n");

exit(0);

}

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (7)

  • 예제 6-16:

    • [예제 6-15]를 개선하여 부모 프로세스는 자식 프로세스의 종료를 기다리면서 종료하는 각 프로세스를 식별하여 메시지와 함께 종료 상태(status)를 출력하는 프로그램을 작성하라.

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (8)

main(int argc,char *argv[])

{

int child1, child2, fork();

int pid, status, wait();

if((child1 = fork()) ==0)

execl("/bin/date","date",(char *) 0);

if((child2 = fork()) ==0)

execl("/bin/who","who",(char *) 0);

printf("parent: wating for children\n");

while((pid = wait(&status)) != -1) {

if(child1 == pid)

printf("parent: first child: %d\n",(status>>8));

else if(child2 == pid)

printf("parent: second child: %d\n",(status>>8));

}

printf("parent: all children terminated\n");

exit(0);

}

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (9)

  • 예제 6-17:

    • C 라이브러리 system() 함수처럼 LINUX 명령어를 매개 변수로 받아 수행시켜 주는 모듈을 fork와 execlp, 그리고 wait 함수를 이용하여 작성하라.

    • 모듈 이름을 command()라 하고 main에서 LINUX 명령어를 매개 변수로 전달하여 실행시킨다.

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (10)

command(char *cmd) /* run a shell command from C program */

{

int chpid, fork();

int w, status, wait();

if((chpid = fork()) == 0) {

execlp("sh","sh","-c",cmd,(char *) 0);

exit(127);

}

while((w = wait(&status)) != chpid && w != -1) ;

if(w == -1) status = -1;

return(status >> 8);

}

main()

{

printf("%d\n", command("date > Date; cat Date"));

printf("%d\n", command("who am i"));

}

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (11)

  • 예제 6-18:

    • fork 함수를 이용하여 자식 프로세스를 생성하고 자식 프로세스에서 execl 함수로 LINUX 명령어를 실행시켜 긴 화일을 출력(cat 명령어 이용)하는 동안 부모 프로세스가 기다리는 프로그램을 작성하라.

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (12)

main(int argc, char *argv[])

{

int pid;

int ret, status;

if((pid = fork()) == 0) /* child */

execl("/bin/cat","cat","/etc/group", (char *) 0);

printf("parent: wating for child: %d\n",pid);

ret = wait(&status);

printf("parent: wait's return value: %d,",ret);

printf("child's status: %d\n", (status >> 8));

exit(0);

}

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (13)

  • 예제 6-19:

    • 인수(argument)로 받은 명령어를 자식 프로세스를 생성하여 수행시키고(execvp 함수 이용), 명령어의 종료 상태(exit status)를 출력하는 프로그램을 작성하라.

Linux System Programming


Linux system programming

프로세스의 종료를 기다림 (14)

main(int argc, char *argv[])

{

int fork();

int status, wait();

if(fork() == 0) {

execvp(argv[1], &argv[1]);

perror(argv[1]);

exit(127);

}

wait(&status);

printf("exit status: %d\n", (status >> 8));

exit(0);

}

Linux System Programming


Linux system programming

예제 프로그램: mini-shell

  • 예제 6-20:

    • Linux 시스템의 셀 인터프리터를 간단하게 구현한 프로그램을 작성하여라.

    • 프로그램 모듈:

      • Ex6-20.h : 최대 인수 수(MAXARG), 최대 명령어 수(MAXCMD) 및 명령어의 구조체를 선언한다

      • Ex6-20a.c : 키보드로 입력된 명령어들의 문법을 검사하고 인수를 분리하여 저장한다

      • Ex6-20b.c : 프롬프트를 표시하고 명령어를 입력 받는다

      • Ex6-20.c : 주프로그램으로서 ex6-20b와 ex6-20a 함수를 호출하고 자식 프로세스를 생성하여 명령어를 실행시킨다

Linux System Programming


  • Login