Child Process\n"); if (execlp("ls", "ls", "-a", (char *)NULL) == -1) { perror("execlp"); exit(1); } exit(0); break; default : /* parent process */ printf("--> Parent process - My PID:%d\n“,(int)getpid()); break; return 0; 28 } 자식프로세스에서 execlp 함수 실행 부모프로세스는 이 부분 실행 # ex6_7.out --> Child Process ex6_1.c ex6_3.c ex6_5.c ex6_6_arg.c ex6_7.out ex6_2.c ex6_4.c ex6_6.c ex6_7.c han.txt --> Parent process - My PID:10535"> Child Process\n"); if (execlp("ls", "ls", "-a", (char *)NULL) == -1) { perror("execlp"); exit(1); } exit(0); break; default : /* parent process */ printf("--> Parent process - My PID:%d\n“,(int)getpid()); break; return 0; 28 } 자식프로세스에서 execlp 함수 실행 부모프로세스는 이 부분 실행 # ex6_7.out --> Child Process ex6_1.c ex6_3.c ex6_5.c ex6_6_arg.c ex6_7.out ex6_2.c ex6_4.c ex6_6.c ex6_7.c han.txt --> Parent process - My PID:10535">
Download presentation
Presentation is loading. Please wait.
1
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
exec 함수군과 fork 함수 fork로 생성한 자식 프로세스에서 exec 함수군을 호출 자식 프로세스의 메모리 이미지가 부모 프로세스 이미지에서 exec 함수로 호출한 새로운 명령으로 대체 자식 프로세스는 부모 프로세스와 다른 프로그램 실행 가능 부모 프로세스와 자식 프로세스가 각기 다른 작업을 수행해야 할 때 fork와 exec 함수를 함께 사용
2
[예제 6-7] fork와 exec 함수 사용하기 (test1.c)
... 06 int main(void) { pid_t pid; 08 switch (pid = fork()) { case -1 : /* fork failed */ perror("fork"); exit(1); break; case 0 : /* child process */ printf("--> Child Process\n"); if (execlp("ls", "ls", "-a", (char *)NULL) == -1) { perror("execlp"); exit(1); } exit(0); break; default : /* parent process */ printf("--> Parent process - My PID:%d\n“,(int)getpid()); break; return 0; 28 } 자식프로세스에서 execlp 함수 실행 부모프로세스는 이 부분 실행 # ex6_7.out --> Child Process ex6_1.c ex6_3.c ex6_5.c ex6_6_arg.c ex6_7.out ex6_2.c ex6_4.c ex6_6.c ex6_7.c han.txt --> Parent process - My PID:10535
3
프로세스 동기화 부모 프로세스와 자식 프로세스의 파일 공유 test2.c
4
프로세스 동기화 부모 프로세스와 자식 프로세스의 종료절차 좀비프로세스 고아프로세스
부모 프로세스와 자식 프로세스는 순서와 상관없이 실행하고 먼저 실행을 마친 프로세스는 종료 부모 프로세스와 자식 프로세스 사이에 종료절차가 제대로 진행되지 않으면 좀비 프로세스 발생 좀비프로세스 실행을 종료하고 자원을 반납한 자식 프로세스의 종료 상태를 부모 프로세스가 가져가지 않으면 좀비 프로세스 발생 좀비 프로세스는 프로세스 테이블에만 존재 좀비 프로세스는 일반적인 제거 방법은 없음 좀비 프로세스를 방지하기 위해 부모 프로세스와 자식 프로세스를 동기화 해야함 고아프로세스 자식 프로세스보다 부모 프로세스가 먼저 종료할 경우 자식 프로세스들은 고아 프로세스가 됨 고아 프로세스는 1번 프로세스(init)의 자식 프로세스로 등록
5
프로세스 동기화 함수[1] 프로세스 동기화: wait(3) #include <sys/types.h>
stat_loc : 상태정보를 저장할 주소 wait 함수는 자식 프로세스가 종료할 때까지 부모 프로세스를 기다리게 함 부모 프로세스가 wait 함수를 호출하기 전에 자식 프로세스가 종료하면 wait 함수는 즉시 리턴 wait 함수의 리턴값은 자식 프로세스의 PID 리턴값이 -1이면 살아있는 자식 프로세스가 하나도 없다는 의미 #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *stat_loc);
6
[예제 6-8] wait 함수 사용하기 (test3.c)
... 07 int main(void) { int status; pid_t pid; switch (pid = fork()) { case -1 : /* fork failed */ perror("fork"); exit(1); break; case 0 : /* child process */ printf("--> Child Process\n"); exit(2); break; default : /* parent process */ while (wait(&status) != pid) continue; printf("--> Parent process\n"); printf("Status: %d, %x\n", status, status); printf("Child process Exit Status:%d\n”,status >> 8); break; } return 0; 30 } # ex6_8.out --> Child Process --> Parent process Status: 512, 200 Child process Exit Status:2 자식 프로세스의 종료를 기다림 오른쪽으로 8비트 이동해야 종료 상태값을 알 수 있음
7
특정 자식 프로세스와 동기화: waitpid(3)
프로세스 동기화 함수[2] 특정 자식 프로세스와 동기화: waitpid(3) pid에 지정할 수 있는 값 -1보다 작은 경우 : pid의 절댓값과 같은 프로세스 그룹ID에 속한 자식 프로세스 중 임의의 프로세스의 상태값 요청 -1인 경우 : wait 함수처럼 임의의 자식 프로세스의 상태값을 요청 0인 경우 : 함수를 호출한 프로세스와 같은 프로세스 그룹에 속한 임의의 프로세스의 상태값 요청 0보다 큰 경우 : 지정한 PID의 상태값 요청 options: waitpid 함수의 리턴 조건 WCONTINUED: 수행중인 자식 프로세스의 상태값 리턴 WNOHANG: pid로 지정한 자식프로세스의 상태값을 즉시 리턴받을 수 없어도 이를 호출한 프로세스의 실행을 블록하지 않고 다른 작업을 수행토록 함 WNOWAIT: 상태값을 리턴한 프로세스가 대기 상태에 머물 수 있도록 함 WUNTRACED: 실행을 중단한 자식 프로세스의 상태값을 리턴 #include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *stat_loc, int options);
8
[예제 6-9] waitpid 함수 사용하기 (test4.c)
... 07 int main(void) { int status; pid_t pid; 10 if ((pid = fork()) < 0) { /* fork failed */ perror("fork"); exit(1); } 15 if (pid == 0) { /* child process */ printf("--> Child process\n"); sleep(3); exit(3); } 21 printf("--> Parent process\n"); 23 while (waitpid(pid, &status, WNOHANG) == 0) { printf("Parent still wait...\n"); sleep(1); } 28 printf("Child Exit Status : %d\n", status>>8); 30 return 0; 32 } # ex6_9.out --> Child process --> Parent process Parent still wait... Child Exit Status : 3 WNOHANG이므로 waitpid 함수는 블록되지 않고 25~26행 반복 실행
9
실습 fork 함수를 사용해 자식 프로세스에서는 로그인한 사용자의 정보를 출 력하고, 부모 프로세스에서는 현재 시간을 출력하도록 하는 프로그램을 작성하라 system(“who”) system(“date”)
10
목차(Chapter 9) 파이프의 개념 이름없는 파이프 만들기 복잡한 파이프 생성 양방향 파이프 활용 이름있는 파이프 만들기
11
파이프의 개념 파이프 간단한 파이프 생성 두 프로세스간에 통신할 수 있도록 해주는 특수 파일
그냥 파이프라고 하면 일반적으로 이름없는 파이프를 의미 이름 없는 파이프는 부모-자식 프로세스 간에 통신할 수 있도록 해줌 파이프는 기본적으로 단방향 간단한 파이프 생성 command : 쉘 명령 mode : “r”(읽기전용 파이프) 또는 “w”(쓰기전용 파이프) fork함수를 실행해 자식 프로세스를 만들고 command에서 지정한 명령을 exec 함수로 자식이 실행하도록 한다: execl(“/bin/sh”, “sh”, “-c”, command, (char *)0); waitpid함수를 수행하여 자식 프로세스들이 종료하기를 기다린다. 리턴값은 자식 프로세스의 종료상태이며, 실패하면 -1을 리턴한다 #include <stdio.h> FILE *popen(const char *command, const char *mode); #include <stdio.h> int pclose(FILE *stream);
12
[예제 9-1] popen 함수 사용하기(test5.c)
... 04 int main(void) { FILE *fp; int a; 07 fp = popen("wc -l", "w"); if (fp == NULL) { fprintf(stderr, "popen failed\n"); exit(1); } 13 for (a = 0; a < 100; a++) fprintf(fp, "test line\n"); 16 pclose(fp); 18 return 0; 20 } “w”모드로 파이프 생성 자식프로세스는 wc –l 명령 수행 자식 프로세스로 출력 결과는 무엇일까?
13
[예제 9-2] popen 함수 사용하기(test6.c)
... 04 int main(void) { FILE *fp; char buf[256]; 07 fp = popen("date", "r"); if (fp == NULL) { fprintf(stderr, "popen failed\n"); exit(1); } 13 if (fgets(buf, sizeof(buf), fp) == NULL) { fprintf(stderr, "No data from pipe!\n"); exit(1); } 18 printf("line : %s\n", buf); pclose(fp); 21 return 0; 23 } 자식 프로세스는 date 명령 실행 읽기모드로 파이프생성 파이프에서 데이터 읽기 # ex9_2.out line : 2010년 2월 5일 금요일 오후 11시 20분 40초
14
복잡한 파이프 생성[1] 파이프 만들기: pipe(2) pipe 함수로 통신과정 (test7.c)
파이프로 사용할 파일기술자 2개를 인자로 지정 fildes[0]는 읽기, fildes[1]은 쓰기용 파일 기술자 pipe 함수로 통신과정 (test7.c) piep 함수를 호출하여 파이프로 사용할 파일기술자 생성 #include <unistd.h> int pipe(int fildes[2]);
15
복잡한 파이프 생성[2] 2. fork 함수로 자식 프로세스 생성. pipe도 자식 프로세스로 복사됨(test8.c) 3. 통신방향 결정(파이프는 기본적으로 단방향)(test9.c)
16
[예제 9-3] pipe 함수 사용하기(test10.c)
ex9_3.c ... 06 int main(void) { int fd[2]; pid_t pid; char buf[257]; int len, status; 11 if (pipe(fd) == -1) { perror("pipe"); exit(1); } 16 switch (pid = fork()) { case -1 : perror("fork"); exit(1); break; 파이프 생성 fork로 자식 프로세스 생성
17
[예제 9-3] pipe 함수 사용하기(test10.c)
case 0 : /* child */ close(fd[1]); write(1, "Child Process:", 15); len = read(fd[0], buf, 256); write(1, buf, len); close(fd[0]); break; default : close(fd[0]); buf[0] = '\0'; write(fd[1], "Test Message\n", 14); close(fd[1]); waitpid(pid, &status, 0); break; } 37 return 0; 39 } 자식 프로세스는 파이프에서 읽을 것이므로 쓰기용 파일기술자(fd[1])를 닫는다. 파이프에서 읽기 부모 프로세스는 파이프에 쓸 것이므로 읽기용 파일기술자(fd[0])를 닫는다. 파이프에 텍스트를 출력 # ex9_3.out Child Process:Test Message
18
실습 popen, pclose 함수를 사용해 부모 프로세스가 보낸 파일의 내용을 자 식 프로세스가 페이지 단위로 출력하는 프로그램을 작성하라. 출력할 파 일명은 명령행 인자로 받는다 자식 fp1=popen(“more”, “w”) 부모 fp2=fopen(argv[1], “r”); while(fgets(buf, 256, fp) != NULL) fputs(buf, fp1); pipe함수를 이용해 구현하라 execlp(“more”, “more”, buf, (char *)NULL)
Similar presentations