1 / 61

12 장 프로세스

12 장 프로세스. 12.1 프로그램 시작 및 종료. 프로그램 실행 시작. exec 시스템 호출 C 시작 루틴에 명령줄 인수와 환경 변수를 전달하고 프로그램을 실행시킨다 C 시작 루틴 (start-up routine) main 함수를 호출하면서 명령줄 인수 , 환경 변수를 전달 exit( main( argc, argv ) ); 실행이 끝나면 반환값을 받아 OS 로 exit 한다. 프로그램 실행 시작. exit( main( argc, argv ) );. 명령줄 인수 / 환경 변수.

Télécharger la présentation

12 장 프로세스

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 12장 프로세스

  2. 12.1 프로그램 시작 및 종료

  3. 프로그램 실행 시작 • exec 시스템 호출 • C 시작 루틴에 명령줄 인수와 환경 변수를 전달하고 • 프로그램을 실행시킨다 • C 시작 루틴(start-up routine) • main 함수를 호출하면서 명령줄 인수, 환경 변수를 전달 exit( main( argc, argv ) ); • 실행이 끝나면 반환값을 받아 OS로 exit 한다

  4. 프로그램 실행 시작 exit( main( argc, argv ) );

  5. 명령줄 인수/환경 변수 argc: 3 argv: 0 1 2 3 myecho\0 hello\0 world!\0 0

  6. printall.c $ gcc –o printall printall.c $ printall hello world! $ env #include <stdio.h> #include <stdlib.h> /* 모든 명령줄 인수와 환경 변수를 프린트한다 */ int main(int argc, char *argv[]) { int i; char **ptr; extern char **environ; for (i = 0; i < argc; i++) /* 모든 명령줄 인수 프린트 */ printf("argv[%d]: %s \n", i, argv[i]); for (ptr = environ; *ptr != 0; ptr++) /* 모든 환경 변수 값 프린트*/ printf("%s \n", *ptr); exit(0); }

  7. 프로그램 종료 • 정상 종료(normal termination) • main() 실행을 마치고 리턴하면 C 시작 루틴은 이 리턴값을 가지고 exit()을 호출 • 프로그램 내에서 직접 exit()을 호출 • 프로그램 내에서 직접 _exit()을 호출 • 비정상 종료(abnormal termination) • abort() • 프로세스에 SIGABRT 시그널을 보내어 프로세스를 비정상적으로 종료 • 시그널에 의한 종료

  8. 프로그램 종료 • exit() • 모든 열려진 스트림을 닫고(fclose), 출력 버퍼의 내용을 디스크에 쓰는(fflush) 등의 뒷정리 후 프로세스를 정상적으로 종료 • 종료 코드(exit code)를 부모 프로세스에게 전달한다 • _exit()

  9. 12.2 프로세스 구조

  10. 프로세스 • 프로세스는 실행중인 프로그램이다 • 프로그램 실행을 위해서는 • 프로그램의 코드, 데이터, 스택, 힙, U-영역 등이 필요하다 • 프로세스 이미지(구조)는 메모리 내의 프로세스 레이아웃 • 프로그램 자체가 프로세스는 아니다 !

  11. 프로세스 구조 • 프로세스 구조 • 코드(code): executable objectcode • 데이터(data) : global variable & static variable • 힙(heap): dymanic memory allocation • 스택 (stack): runtime stack • U-영역(user-area): open files 교재 373 참조 (root 권한으로) $ cat /proc/1/maps

  12. (참고) Linux 가상 메모리 구조 • 하나의 태스크마다 4GB주소 공간을 할당 • 각 태스크에게 3GB 할당 • 나머지 1GB는 모든 태스크들의 공통 영역으로서 커널 공간으로 할당 $ cat/proc/1/maps BSS(Block Started by Symbol) 운영체제

  13. (참고) Linux 메모리 관리 자료구조 • task_struct구조체내의 struct mm_struct *mm • /usr/src/kernels/linux-2.6.35.6/include/linux/sched.h (1193행 CentOSLinux 2.6.32.71) • /usr/src/kernels/linux-2.6.35.6/include/linux/mm_types.h (222행,131행) • vm_area_struct 안의 structmm_struct * vm_mm은 메모리 디스크립터 포인터 운영체제

  14. 12.3 프로세스 생성

  15. 프로세스 ID • 각 프로세스는 프로세스를 구별하는 번호인 프로세스 ID를 갖고 있다

  16. 프로세스 생성 • fork() 시스템 호출 • 부모 프로세스를 똑같이 복제하여 새로운 자식 프로세스를 생성 • 자기복제(自己複製) • fork()는 한 번 호출되면 두 번 리턴한다 • 자식 프로세스에게는 0을 리턴하고 • 부모 프로세스에게는 자식 프로세스 ID를 리턴한다 • 부모 프로세스와 자식 프로세스는 병행적으로 각각 실행을 계속한다

  17. 프로세스 생성

  18. PC PC PC (예) fork 시스템 호출: onetwo.c #include <stdio.h> main() { int pid; printf("One\n"); pid = fork(); printf("Two\n"); } $ gcc –o onetwo onetwo.c BEFORE fork AFTER 부모 프로세스 자식 프로세스

  19. fork1.c #include <stdio.h> /* 자식 프로세스를 생성한다 */ int main() { int pid; printf("[%d] 프로세스 시작 \n", getpid()); pid = fork(); printf("[%d] 프로세스 : fork() 리턴값 pid=%d\n", getpid(),pid); }

  20. 부모 프로세스와 자식 프로세스 구분 • fork() 호출 후에 리턴값이 다르므로 이 리턴값을 이용하여 • 부모 프로세스와 자식 프로세스를 구별하고 • 서로 다른 일을 하도록 할 수 있다 pid = fork(); if ( pid == 0 ) { 자식 프로세스의 실행 코드 } else { 부모 프로세스의 실행 코드 }

  21. fork2.c: 자식 프로세스 생성 #include <stdlib.h> #include <stdio.h> /* 부모 프로세스가 자식 프로세스를 생성하고 서로 다른 메시지를 프린트 */ int main() { int pid; pid = fork(); if (pid ==0) { // 자식 프로세스 printf("[Child] : Hello, world pid=%d\n",getpid()); } else { // 부모 프로세스 printf("[Parent] : Hello, world pid=%d\n", getpid()); } }

  22. fork3.c: 두 개의 자식 프로세스 생성 #include <stdlib.h> #include <stdio.h> /* 부모 프로세스가 두 개의 자식 프로세스를 생성한다 */ int main() { int pid1, pid2; pid1 = fork(); if (pid1 == 0) { printf("[Child 1] : Hello, world ! pid=%d\n", getpid()); exit(0); /* ① */ } pid2 = fork(); if (pid2 == 0) { printf("[Child 2] : Hello, world ! pid=%d\n", getpid()); exit(0); /* ② */ } } • ①만 없애보세요! • ②만 없애보세요! • ①&② 모두 없애보세요!

  23. 프로세스 기다리기: wait() • 자식 프로세스 중의 하나가 끝날 때까지 기다린다 • 끝난 자식 프로세스의 종료 코드는 status에 저장 • 끝난 자식 프로세스의 번호를 리턴 • 하나 이상의 자식이 이미 좀비라면 좀비 중 하나의 상태를 반환 • (예) zombie.c

  24. zombie.c #include <stdio.h> #include <stdlib.h> main () { int pid; pid = fork (); /* Duplicate */ if (pid != 0) /* Branch based on return value from fork () */ { while (1) /* Never terminate, and never execute a wait () */ sleep (1000); } else { exit (42); /* Exit with a silly number */ } } $ gcc –o zombie zombie.c $ zombie & $ ps 재부팅후 $ ps $ ps ux 또는 $ ps –ef | grep 자기id $ killall zombie

  25. wait(&status) • wait(&status) /* int status */ • status :자식이 exit으로 종료될 때의 상태정보 • 정상종료 경우 : 하위 8 비트는 0, 상위 8 비트는 exit status(자식 프로세스가 exit 명령으로 전달한 값) • signal로 종료된 경우 : 하위 8 비트는 signal 번호, 상위 8 비트는 0 • (하위 8 비트 추출) status & 0x00FF; • (상위 8 비트 추출) status >> 8 & >> 8

  26. forkwait.c: 자식 프로세스 기다리기 #include <stdio.h> #include <stdlib.h> /* 부모 프로세스가 자식 프로세스를 생성하고 끝나기를 기다린다 */ int main() { int pid, child, status; printf("[%d] 부모 프로세스 시작 \n", getpid( )); pid = fork(); if (pid == 0) { printf("[%d] 자식 프로세스 시작 \n", getpid( )); exit(1); } child = wait(&status); // 자식 프로세스가 끝나기를 기다린다. printf("[%d] 자식 프로세스 %d 종료 \n", getpid(), child); printf("\t종료 코드 %d\n", status >> 8); } • 자식 프로세스 종료 코드 하위8비트/상위8비트 구분 출력하기 • 상위8비트/하위8비트로 출력 순서 바꾸면?

  27. 12.4 프로그램 실행

  28. 프로그램 실행 • fork() 후 • 자식 프로세스는 부모 프로세스와 똑같은 코드 실행 • 자식 프로세스에게 새로운 프로그램을 시키려면 어떻게 하여야 할까? • 프로세스 내의 프로그램을 새 프로그램으로 대치 • exec() 시스템 호출 사용 • 보통 fork() 후에 exec( )

  29. 프로그램 실행: exec() • 프로세스가 exec() 호출을 하면, • 그 프로세스 내의 프로그램은 완전히 새로운 프로그램으로 대치 • 자기대치(自己代置) • 새 프로그램의 main()부터 실행이 시작한다

  30. 프로그램 실행: exec() • exec() 호출이 성공하면 리턴할 곳이 없어진다 • 성공한 exec() 호출은 절대 리턴하지 않는다

  31. fork/exec • 보통 fork() 호출 후에 exec() 호출 • 새로 실행할 프로그램에 대한 정보를 arguments로 전달한다 • . • exec() 호출이 성공하면 • 자식 프로세스는 새로운 프로그램을 실행하게 되고 • 부모는 계속해서 다음 코드를 실행하게 된다 if ((pid = fork()) == 0 ){ exec( arguments ); exit(1); } // 부모 계속 실행

  32. PC PC PC PC PC fork와 exec호출의 조합 BEFORE FORK A AFTER FORK A B AFTER FORK AFTER EXEC A B (now runs ls)

  33. execute1.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* 자식 프로세스를 생성하여 echo 명령어를 실행한다 */ int main( ) { printf("부모 프로세스 시작\n"); if (fork( ) == 0) { fprintf(stdout, "자식 프로세스 시작\n"); execl("/bin/echo", "echo", "hello", "world", NULL); fprintf(stderr, "자식 프로세스 실패\n"); exit(1); } printf("부모 프로세스 끝\n"); }  "ls -l"실행하도록 수정하세요!

  34. (응용) execute11.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* 자식 프로세스를 생성하여 echo 명령어를 실행한다 */ int main( ) { char*av[3]; av[0]=“ls"; av[1]=“-l"; av[2]=NULL; printf("부모 프로세스 시작\n"); if (fork( ) == 0) { fprintf(stdout, "자식 프로세스 시작\n"); execv("/bin/ls", av); fprintf(stderr, "자식 프로세스 실패\n"); exit(1); } printf("부모 프로세스 끝\n"); } 0xbffff5c4 0x8048644 av ls\0 0x8048644 0 1 2 0x8048647 -l\0 0x0  "ls -l -i"실행하도록 수정하세요!

  35. execute2.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* 세 개의 자식 프로세스를 생성하여 각각 다른 명령어를 실행한다 */ int main( ) { printf("부모 프로세스 시작\n"); if (fork( ) == 0) { execl("/bin/echo", "echo", "hello", NULL); fprintf(stderr,"첫 번째 실패"); exit(1); } if (fork( ) == 0) { execl("/bin/date", "date", NULL); fprintf(stderr,"두 번째 실패"); exit(2); } if (fork( ) == 0) { execl("/bin/ls","ls", "-l", NULL); fprintf(stderr,"세 번째 실패"); exit(3); } printf("부모 프로세스 끝\n"); }

  36. execute3.c: 자식 프로세스 명령어 실행 $ vi myexit.c #include <stdio.h> #include <stdlib.h> main () { printf ("I'm going to exit with return code\n"); exit (33); } #include <stdio.h> /* 명령줄 인수로 받은 명령을 실행시킨다 */ int main(int argc, char *argv[]) { int child, pid, status; pid = fork( ); if (pid == 0) { // 자식 프로세스 execvp( argv[1], &argv[1] ); fprintf(stderr, "%s:실행 불가\n",argv[1]); } else { // 부모 프로세스 child = wait(&status); printf("[parent: %d] 자식 프로세스 %d 종료 \n", getpid(), pid); printf("[child : %d] 종료 코드 하위: %d 상위: %d \n", child, status & 0x00FF, status >> 8); } } $ gcc –g –o execute3 execute3.c $ execute3 ls –l $ execute3 myexit Q: Why &argv[1] ?

  37. Why &argv[1] ? Q: execvp( argv[1], &argv[1] ); =execvp( ??, ?? ); argc 2 0xbffff684 0xbffff7c5 $ gcc –g –o execute3 execute3.c $ gdb execute3 (gdb) b 6 Breakpoint 1 at 0x80484dd: file execute3.c, line 6. (gdb) b 13 Breakpoint 2 at 0x8048559: file execute3.c, line 13. (gdb) r myexit Starting program: /home/mysung/ulprog/cprog/execute3 myexit Breakpoint 1, main (argc=2, argv=0xbffff684) at execute3.c:6 6 pid = fork( ); (gdb) p argc $1 = 2 (gdb) p argv $2 = (char **) 0xbffff684 (gdb) p &argc $3 = (int *) 0xbffff5e0 (gdb) p &argv $4 = (char ***) 0xbffff5e4 (gdb) p argv[0] $5 = 0xbffff7c5 "/home/mysung/ulprog/cprog/execute3" (gdb) p argv[1] $6 = 0xbffff7e8 "myexit" (gdb) p argv[2] $7 = 0x0 (gdb) p &argv[0] $8 = (char **) 0xbffff684 (gdb) p &argv[1] $9 = (char **) 0xbffff688 (gdb) p &argv[2] $10 = (char **) 0xbffff68c argv 0xbffff684 0 1 2 execute3\0 0xbffff7c5 0xbffff7e8 myexit\0 0x0 (gdb) c Continuing. Detaching after fork from child process 11288. I'm going to exit with return code [parent: 11246] 자식 프로세스 11288 종료 Breakpoint 2, main (argc=2, argv=0xbffff684) at execute3.c:13 13 printf("[child : %d] 종료 코드 하위: %d 상위: %d \n", child, status & 0x00FF, status >> 8 ); (gdb) p status & 0xFF $11 = 0 (gdb) p status >> 8 $12 = 77 (gdb) c Continuing. [child : 11288] 종료 코드 하위: 0 상위: 77 Program exited with code 054. (gdb) quit

  38. (응용) execute33.c: 자식 프로세스 kill #include <stdio.h> #include <stdlib.h> #include <signal.h> /* 명령줄 인수로 받은 명령을 실행시킨다 */ int main(int argc, char *argv[]) { int child, pid, status; pid = fork( ); if (pid == 0) { // 자식 프로세스 execvp(argv[1], &argv[1]); fprintf(stderr, "%s:실행 불가\n",argv[1]); } else { // 부모 프로세스 printf("SIGINT=%d, SIGKILL=%d, SIGTERM=%d\n", SIGINT, SIGKILL, SIGTERM); kill(pid, SIGINT); child = wait(&status); printf("[parent: %d] 자식 프로세스 %d 종료 \n", getpid(), pid); printf("[child : %d] 종료 코드 하위: %d 상위: %d \n", child, status & 0x00FF, status>>8); } } $ gcc -g –o execute33 execute33.c $ execute33 sleep 100  GDB 실행하여확인해 보세요!

  39. $ gdb execute33 0xbffff684 0xbffff7c0 argc 3 argv 0 1 2 3 0xbffff684 execute33\0 0xbffff7c0 $ gcc -g -o execute33 execute33.c $ gdb execute33 (gdb) b 8 Breakpoint 1 at 0x804850d: file execute33.c, line 8. (gdb) b 14 Breakpoint 2 at 0x8048583: file execute33.c, line 14. (gdb) r sleep 100 Starting program: /home/mysung/ulprog/cprog/execute33 sleep 100 Breakpoint 1, main (argc=3, argv=0xbffff684) at execute33.c:8 8 pid = fork( ); (gdb) p &argc $1 = (int *) 0xbffff5e0 (gdb) p &argv $2 = (char ***) 0xbffff5e4 (gdb) p argv[0] $3 = 0xbffff7c0 "/home/mysung/ulprog/cprog/execute33" (gdb) p argv[1] $4 = 0xbffff7e4 "sleep" (gdb) p argv[2] $5 = 0xbffff7ea "100" (gdb) p argv[3] $6 = 0x0 (gdb) p pid $7 = 8065012 (gdb) n Detaching after fork from child process 11893. 9 if (pid == 0) { // 자식 프로세스 (gdb) p pid $8 = 11893 (gdb) n 13 printf("SIGINT=%d, SIGKILL=%d, SIGTERM=%d\n", SIGINT, SIGKILL, SIGTERM); (gdb) c Continuing. SIGINT=2, SIGKILL=9, SIGTERM=15 Breakpoint 2, main (argc=3, argv=0xbffff684) at execute33.c:14 14 kill(pid, SIGKILL); 0xbffff7e4 sleep\0 0xbffff7ea 100\0 0x0 (gdb) p pid $7 = 11893 (gdb) p SIGKILL No symbol "SIGKILL" in current context. (gdb) n 15 child = wait(&status); (gdb) p child $8 = 134514203 (gdb) p status $9 = 134513744 (gdb) n 16 printf("[parent: %d] 자식 프로세스 %d 종료 \n", getpid(), pid); (gdb) p getpid() $10 = 11888 (gdb) p pid $11 = 11893 (gdb) n [parent: 11888] 자식 프로세스 11893 종료 17 printf("[child : %d] 종료 코드 상위: %d 하위: %d \n", child, status>>8, status & 0x00FF); (gdb) p child $12 = 11893 (gdb) p status $13 = 9 (gdb) p status >> 8 $14 = 0 (gdb) p status & 0x00ff $15 = 9 (gdb) quit

  40. (시험예시) run.c ① argc: #include <stdio.h> #include <stdlib.h> #include <signal.h> /* 명령줄 인수로 받은 명령을 실행시킨다 */ int main(int argc, char *argv[]) { int child, pid, status; pid = fork( ); if (pid == 0) { // 자식 프로세스 execvp(argv[1], &argv[1]); fprintf(stderr, "%s:실행 불가\n",argv[1]); } else { // 부모 프로세스 /* kill(pid, SIGKILL); */ child = wait(&status); printf("[parent: %d] 자식 프로세스 %d 종료 \n", getpid(), pid); printf("[child : %d] 종료 코드 하위: %d 상위: %d \n", child, status & 0x00FF, status>>8); } } ③ ② run\0 argv: ④ sleep\0 ⑤ 100\0 0 $ gcc –g –o run.c run $ run

  41. (시험 예시) $ gdb run 0xbffff674 0xbffff7b7 argc 3 $ gcc -g -o run run.c $ gdb run (gdb) b 8 Breakpoint 1 at 0x804850d: file run.c, line 8. (gdb) r sleep 100 Starting program: /home/mysung/59bu/mytest/x2013ul/run sleep 100 Breakpoint 1, main (argc=3, argv=0xbffff674) at run.c:8 8 pid = fork( ); (gdb) p &argc $1 = (int *) 0xbffff5d0 (gdb) p &argv $2 = (char ***) 0xbffff5d4 (gdb) p argv[0] $3 = 0xbffff7b7 "/home/mysung/59bu/mytest/x2013ul/run" (gdb) p argv[1] $4 = 0xbffff7dc "sleep" (gdb) p argv[2] $5 = 0xbffff7e2 "100" (gdb) p argv[3] $6 = 0x0 (gdb) p &argv[0] $7 = (char **) 0xbffff674 (gdb) p &argv[1] $8 = (char **) 0xbffff678 (gdb) p &argv[2] $9 = (char **) 0xbffff67c (gdb) p &argv[3] $10 = (char **) 0xbffff680 (gdb) n Detaching after fork from child process 28803. 9 if (pid == 0) { // 자식 프로세스 argv (gdb) p pid $11 = 28803 (gdb) n 13 kill(pid, SIGKILL); (gdb) p pid $12 = 28803 (gdb) p SIGKILL No symbol "SIGKILL" in current context. (gdb) n 14 child = wait(&status); (gdb) n 15 printf("[parent: %d] 자식 프로세스 %d 종료 \n", getpid(), pid); (gdb) p getpid() $13 = 28660 (gdb) p pid $14 = 28803 (gdb) n [parent: 28660] 자식 프로세스 28803 종료 16 printf("[child : %d] 종료 코드 상위: %d 하위: %d \n", child, status>>8, status & 0x00FF); (gdb) p child $15 = 28803 (gdb) p status>>8 $16 = 0 (gdb) p status & 0x00FF $17 = 9 (gdb) p status $18 = 9 (gdb) quit 0 1 2 3 0xbffff7b7 0xbffff674 run\0 0xbffff7dc sleep\0 0xbffff7e2 100\0 0x0

  42. 12.5 입출력 재지정

  43. fd1 파일 fd2 fd3 입출력 재지정 • 명령어의 표준 출력이 파일에 저장 $ 명령어 > 파일 • 출력 재지정 기능 구현 dup() 혹은 dup2() 시스템 호출 • 파일 디스크립터 fd를 표준출력(1)에 dup2() fd = open(argv[1], O_CREAT|O_TRUNC|O_WRONLY, 0600); dup2(fd, 1);

  44. (참고) inode (indexnode) 구조 • Linux CentOS 2.6.32-71.el6.i686 #1 SMP • /usr/include/linux/ext2_fs.h • struct ext2_inode /* ext2_fs.h 208행 */ • /* ext2_fs.h 77행 reserved inode bumbers */ #define EXT2_BAD_INO 1 /* Bad blocks inode */ #define EXT2_ROOT_INO 2 /* Root inode */ #define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ #define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ /* First non-reserved inode for old ext2 filesystems */ #define EXT2_GOOD_OLD_FIRST_INO 11 • /usr/src/kernels/2.6.43.8-1.fc15.i686/include/linux/fs.h • struct file /* fs.h 971행 */ • struct address_space /* fs.h 641행 */ • struct inode /* fs.h 756행 */ • Solaris 10 • /usr/include/sys/file.h 및 vnode.h • typedef struct file /* file.h 43행 */ • typedefstruct vnode /* vnode.h 243행

  45. redirect1.c: 표준출력 재지정 #include <stdio.h> #include <fcntl.h> /* 표준 출력을 파일에 재지정하는 프로그램 */ int main(int argc, char* argv[]) { int fd, status; fd = open(argv[1], O_CREAT | O_TRUNC | O_WRONLY, 0600); dup2(fd, 1); /* 파일을 표준출력에 복제 */ close(fd); printf("Hello stdout !\n"); fprintf(stderr,"Hello stderr !\n"); } $ gcc –o redirect1 redirect1.c $ redirect1 xx

  46. redirect2.c: 자식 프로세스 표준출력 재지정 #include <stdio.h> #include <fcntl.h> /* 자식 프로세스의 표준 출력을 파일에 재지정한다 */ int main(int argc, char* argv[]) { int child, pid, fd, status; pid = fork( ); if (pid == 0) { fd = open(argv[1],O_CREAT | O_TRUNC| O_WRONLY, 0600); dup2(fd, 1); // 파일을 표준출력에 복제 close(fd); execvp(argv[2], &argv[2]); fprintf(stderr, "%s:실행 불가\n",argv[1]); } else { child = wait(&status); printf("[%d] 자식 프로세스 %d 종료 \n", getpid(), child); } } $ gcc –o redirect2 redirect2.c $ redirect2 xx ls –l  $ ls –l > xx (redirect out) 원리

  47. 기타 시스템 호출

  48. 12.6 시스템 부팅

  49. 시스템 부팅 • 시스템 부팅은 fork/exec 시스템 호출을 통해 이루어진다 $ psalx | more $ ps–ef | more (root 권한으로) $ cat /proc/1/maps  같은 pid!

  50. 시스템 부팅 • swapper(스케줄러 프로세스) • 커널 내부에서 만들어진 프로세스로 프로세스 스케줄링을 한다 • init(초기화 프로세스) • /etc/inittab 파일에 기술된 대로 시스템을 초기화 • getty 프로세스 • 로그인 프롬프트를 내고 키보드 입력을 감지한다 • login 프로세스 • 사용자의 로그인 아이디 및 패스워드를 검사 • shell 프로세스 • 시작 파일을 실행한 후에 쉘 프롬프트를 내고 사용자로부터 명령어를 기다린다

More Related