1 / 48

Linux/UNIX Programming APUE (Process Control) [Ch. 8] 최 미 정 강원대학교 컴퓨터과학전공

Linux/UNIX Programming APUE (Process Control) [Ch. 8] 최 미 정 강원대학교 컴퓨터과학전공. 강의 내용. APUE (Process Control). 프로세스 ID 프로세스 생성 프로세스 종료 레이스 컨디션 프로그램 실행 기타. Process Identifiers (1/2). APUE (Process Control).

gilon
Télécharger la présentation

Linux/UNIX Programming APUE (Process Control) [Ch. 8] 최 미 정 강원대학교 컴퓨터과학전공

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. Linux/UNIX Programming APUE (Process Control) [Ch. 8] 최 미 정 강원대학교 컴퓨터과학전공

  2. 강의 내용 APUE (Process Control) • 프로세스 ID • 프로세스 생성 • 프로세스 종료 • 레이스 컨디션 • 프로그램 실행 • 기타

  3. Process Identifiers (1/2) APUE (Process Control) • Every process has a unique process ID, a nonnegative integer.(모든 프로세스는 양수의 유일한 식별자(PID)를 가짐) • Process ID 0: swapper • scheduler process (it controls time slots for processes) • system process • part of the kernel • no program on disk corresponds to this process

  4. Process Identifiers (2/2) APUE (Process Control) • Process ID 1: init process • invoked by the kernel at the end of the bootstrap procedure • /etc/init or /sbin/init • reads the system-dependent initialization files (/etc/rc*) • brings the system to a certain state (multi-user) • a normal user process but runs with super-user privileges • PID 1 is immortal • Process ID 2: pagedaemon • supports the paging of the virtual memory system • kernel process

  5. System Process 예제 APUE (Process Control)

  6. PID 관련 함수 APUE (Process Control) #include <sys/types.h> #include <unistd.h> pid_t getpid(void); // returns process ID pid_t getppid(void); // returns parent process ID uid_t getuid(void); // returns real user ID uid_t geteuid(void); // returns effective user ID gid_t getgid(void); // returns real group ID gid_t getegid(void); // returns effective group ID • None of these functions has an error return.

  7. 강의 내용 APUE (Process Control) • 프로세스 ID • 프로세스 생성 • 프로세스 종료 • 레이스 컨디션 • 프로그램 실행 • 기타

  8. fork() (1/3) APUE (Process Control) #include <sys/types.h> #include <unistd.h> pid_t fork(void); • fork() is the ONLY way to create a process in Unix kernel. • Child process is the new process created by fork(). • fork() is called once, but returns twice! • returns 0 in child process. • returns the child process ID in parent process.

  9. fork() (2/3) APUE (Process Control) • Child gets a copy of parent’s data space, heap, and stack • Often, read-only text segment is shared • Parent and child continue executing instructionsfollowing the fork() call • Often, fork() is followed by exec().

  10. fork() (3/3) APUE (Process Control)

  11. 예제: fork.c (1/2) APUE (Process Control) #include <stdio.h> #include <unistd.h> #include <sys/types.h> err_sys(char *p) { perror(p); exit(-1); } int tglob = 6; /* external variable in initialized data */ int main(void) { int tvar; /* automatic variable on the stack */ pid_t pid; tvar = 88; if ((pid = fork()) < 0) err_sys("fork"); else if(pid == 0) { /* child */ tglob++; /* modify variables */ tvar++; } else /* parent */ sleep(2); printf("pid = %d, tglob = %d, tvar = %d\n", getpid(), tglob, tvar); exit(0); }

  12. 예제: fork.c (2/2) APUE (Process Control) • 실행 결과

  13. parent process table entry v-node table file table v-node information fd status flags file descriptors current file offset i-node information fd flags ptr fd 0: v-node ptr fd 1: fd 2: current file size fd status flags . . . . current file offset v-node information v-node ptr child process table entry i-node information fd status flags current file offset file descriptors current file size v-node ptr fd flags ptr fd 0: fd 1: v-node information fd 2: . . . . i-node information current file size File Sharing after fork() APUE (Process Control) • Parent and child share the same file descriptors. • Parent and child share the same file offset. • Therefore, intermixed output will occur from parent and child.

  14. Properties Inherited to the Child APUE (Process Control) • real user and group ID, effective user and group ID • supplementary group IDs • process group ID, session ID • set-user-ID and set-group ID flags • current working directory • root directory • file mode creation mask • signal mask and dispositions • the close-on-exec flag for any open file descriptors • environment • attached shared memory segments • resource limits

  15. Properties NOT Inherited to the Child APUE (Process Control) • the return value from fork() • the process IDs are different • file locks • pending alarms are cleared for the child • the set of pending signals for the child is set to the empty set

  16. 강의 내용 APUE (Process Control) • 프로세스 ID • 프로세스 생성 • 프로세스 종료 • 레이스 컨디션 • 프로그램 실행 • 기타

  17. exit() – Process Termination APUE (Process Control) • A process can terminate in 5 ways: • Normal Termination • return from main() • exit()  w/ cleanup procedure • _exit()  w/o cleanup procedure • Abnormal Termination • calling abort() (generates SIGABRT signal) • process receives signals

  18. exit() – Termination Status APUE (Process Control) • Exit Status: • argument of exit(), _exit() • the return value from main() • Termination Status: • Normal termination: Exit status  Termination status • Abnormal termination: kernel indicates reason  Termination status • Parent can obtain the termination status of the child process. • by wait() or waitpid() • What if parent terminates before child? • init(PID = 1) becomes the parent of the child process

  19. exit() – Child Termination  skip APUE (Process Control) • Suppose child terminates first • If child disappeared, parent would not be able to check child’s termination status. • Zombie: minimal info of dead child process (pid, termination status, CPU time) kept by the kernel for the parent to call wait() or waitpid()  Zombie가 되지 않도록 하기 위해서는 Parent가 wait()해 주어야 함

  20. wait(), waitpid() (1/2) APUE (Process Control) • Child terminates • Kernel sends SIGCHLD signal to parent. • an asynchronous event • Default action for signal: ignore it. • Signal handlers can be defined by users • call wait() to fetch the termination status of child. • (무사히, 죽을 수 있도록 배려~)

  21. wait(), waitpid() (2/2) APUE (Process Control) #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); Both returns: process ID if OK, 0, or -1 on error • A process that calls wait or waitpid can • block (if all of its children are still running), or • return immediately with the termination status of a child, or • return immediately with an error (if it doesn’t have any child processes) • statloc • a pointer to an integer to store the termination status • options: refer to manual of waitpid()

  22. Macros to examine the termination status  skip APUE (Process Control)

  23. 예제: nwait.c (1/3)  skip APUE (Process Control) #include <stdio.h> // nwait.c #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> void pr_exit(int status) { if (WIFEXITED(status)) printf("normal termination, exit status = %d\n“, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) printf("abnormal termination, signal number = %d\n", WTERMSIG(status)); else if (WIFSTOPPED(status)) printf("child stopped, signal number = %d\n", WSTOPSIG(status)); }

  24. 예제: nwait.c (2/3)  skip APUE (Process Control) int main(void) { pid_t pid; int status; if((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) exit(7); /* child */ if(wait(&status) != pid) err_sys("wait error"); /* wait for child */ pr_exit(status); if((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ abort(); /* generates SIGABRT */ if(wait(&status) != pid) err_sys("wait error"); /* wait for child */ pr_exit(status); if((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ status /= 0; /* divide by 0 generates SIGFPE */ if(wait(&status) != pid) err_sys("wait error"); /* wait for child */ pr_exit(status); exit(0); }

  25. 예제: nwait.c (3/3)  skip APUE (Process Control) • 실행 결과

  26. 강의 내용 APUE (Process Control) • 프로세스 ID • 프로세스 생성 • 프로세스 종료 • 레이스 컨디션 • 프로그램 실행 • 기타

  27. Race Conditions (1/2) APUE (Process Control) • Multiple processes share some data. • Outcome depends on the order of their execution (i.e. RACE) • (Process A) x = 20; • (Process B) x += 10; • After fork(), we cannot predict if the parent or the child runs first! • The order of execution depends on: • System Load • Kernel’s Scheduling Algorithm

  28. Race Conditions (2/2) APUE (Process Control) • For parent to wait for child, • Call wait(), waitpid(), wait3(), wait4() • Use signals or other IPC methods • For child to wait for parent, • while(getppid() != 1) sleep(1); // Parent가 죽을 때까지 기다림 • Use signals or other IPC methods

  29. 예제: race.c (1/2) APUE (Process Control) #include <stdio.h> // race.c #include <sys/types.h> err_sys(char *p) { perror(p); exit(-1); } int main(void) { pid_t pid; if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) charatatime("output from child\n"); else charatatime("output from parent\n"); exit(0); } charatatime(char *str) { char *ptr; int c; for (ptr = str; c = *ptr++; ) { putc(c, stdout); fflush(stdout); usleep(1); } }

  30. 예제: race.c (2/2) APUE (Process Control) • 실행 결과

  31. How to Avoid Race Condition? APUE (Process Control) #include <stdio.h> #include <sys/types.h> int main(void) { pid_t pid; TELL_WAIT(); if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) { WAIT_PARENT(); // parent goes first charatatime("output from child\n"); } else { charatatime("output from parent\n"); TELL_CHILD(pid); } exit(0); } • How to implement TELL_WAIT(), WAIT_PARENT(), and TELL_CHILD()? • Use signals (Ch. 10) • Use IPC methods (Ch. 14 and 15)

  32. 강의 내용 APUE (Process Control) • 프로세스 ID • 프로세스 생성 • 프로세스 종료 • 레이스 컨디션 • 프로그램 실행 • 기타

  33. Program Execution: exec() (1/2) APUE (Process Control) • When a process calls one of the exec functions • that process is completely replaced by the new program (새로운 프로그램으로 대체)(text, data, heap, and stack segments) • and the new program starts at its main function • 함수 exec()를 호출하여 완전히 다른 프로그램으로 실행된다. #include <unistd.h> /* exec_echo.c */ int main() { execl("/bin/echo", "echo", "execute /bin/echo", (char*) 0); printf("Can this message be printed? ERROR!\n"); } $ a.out execute /bin/echo

  34. Program Execution: exec() (2/2) APUE (Process Control)

  35. exec() Functions APUE (Process Control) #include <unistd.h> int execl(const char *pathname, const char *arg0, … /* (char*) 0 */); int execv(const char *pathname, const char *argv[]); int execle(const char *pathname, const char *arg0, … /* (char*) 0, char *const envp[] */); int execve(const char *pathname, const char *argv[],char *const envp[]); int execlp(const char *filename, const char *arg0, … /* (char*) 0 */); int execvp(const char *filename, const char *argv[]); All six return: -1 on error, no return on success • exec? (p, l, v, e) • p: filename (not pathname) • l: takes a list of arguments (the last argument should be a null pointer) • v: takes argv[] vector • e: takes envp[] array without ‘e’, the environment variables of the calling proces are copied

  36. Properties inherited to the new program APUE (Process Control) • same ID • process ID, parent process ID, real user ID, real group ID, supplementary group IDs, process group ID, session ID • controlling terminal • time left until alarm clock • current working directory • root directory • file mode creation mask • file locks • process signal mask • pending signals • resource limits, …

  37. 예제: nexec.c, echoall.c (1/3) APUE (Process Control) #include <stdio.h> // nexec.c #include <sys/types.h> #include <sys/wait.h> err_sys(char *p) { perror(p); exit(-1); } char *env_init[] = { "USER=unknown", "PATH=/tmp", NULL }; int main(void) { pid_t pid; if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) { /* specify pathname, specify environment */ if (execle("/home/prof/ysmoon/unix/APUE/echoall", "echoall", "myarg1", "MY ARG2", (char *)0, env_init) < 0) err_sys("execle error"); } if (waitpid(pid, NULL, 0) < 0) err_sys("wait error"); putchar('\n'); if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) { /* specify filename, inherit environment */ if (execlp("echoall", "echoall", "only 1 arg", (char *) 0) < 0) err_sys("execlp error"); } exit(0); }

  38. 예제: nexec.c, echoall.c (2/3) APUE (Process Control) #include <stdio.h> // echoall.c int main(int argc, char *argv[]) { int i; char **ptr; extern char **environ; for (i = 0; i < argc; i++) /* echo all command-line args */ printf("argv[%d]: %s\n", i, argv[i]); for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */ printf("%s\n", *ptr); exit(0); }

  39. 예제: nexec.c, echoall.c (3/3) APUE (Process Control) • 실행 결과

  40. 강의 내용 APUE (Process Control) • 프로세스 ID • 프로세스 생성 • 프로세스 종료 • 레이스 컨디션 • 프로그램 실행 • 기타

  41. system() APUE (Process Control) #include <stdlib.h> int system(const char *cmdstring); • 주어진 스트링(cmdstring)을 Shell 상에서 수행시킨다. • e.g.) system(“date > file”); • system() is implemented by calling fork, exec, and waitpid. • Return values: • -1 with errno: fork or waitpid fails • 127: exec fails • Termination status of shell: all 3 functions succeed

  42. 예제: system.c APUE (Process Control) #include <sys/types.h> // system.c #include <sys/wait.h> #include <errno.h> #include <unistd.h> int system(const char *cmdstring) /* version without signal handling */ { pid_t pid; int status; if(cmdstring == NULL) return(1); /* always a command processor with Unix */ if((pid = fork()) < 0) { status = -1; /* probably out of processes */ } else if (pid == 0) { /* child */ execl("/bin/sh", "sh", "-c", cmdstring, (char *) 0); _exit(127); /* execl error */ } else { /* parent */ while (waitpid(pid, &status, 0) < 0) if (errno != EINTR) { status = -1; /* error other than EINTR from waitpid() */ break; } } return(status); }

  43. 예제: myls.c (1/2) APUE (Process Control) #include <stdio.h> // myls.c main(int ac, char *av[]) { int i; char cmdstr[1024]; strcpy(cmdstr, "/bin/ls "); for(i=1;i < ac;i++) { strcat(cmdstr, av[i]); strcat(cmdstr, " "); } fprintf(stdout, "cmdstr = \"%s\"\n", cmdstr); system(cmdstr); exit(0); }

  44. 예제: myls.c (2/2) APUE (Process Control) • 실행 결과

  45. Process Times APUE (Process Control) #include <sys/times.h> clock_t times(struct tms *buf); Returns: elapsed wall clock time in clock ticks if OK, -1 on error struct tms ( clock_t tms_utime; /* user cpu time */ clock_t tms_stime; /* system cpu time */ clock_t tms_cutime; /* child user cpu time */ clock_t tms_cstime; /* child system cpu time */ } • Wall clock time: the amount of time the process takes to run and depends on the system loads. (실제 수행된 시간) • User CPU time: attributed to user instructions(사용자 코드에 의해 CPU를 점유한 시간) • System CPU time: attributed to the kernel, when it executes on behalf of the process (시스템 코드에 의해 CPU를 점유한 시간)

  46. 예제: times.c (1/3) APUE (Process Control) #include <stdio.h> // times.c #include <unistd.h> #include <sys/times.h> err_sys(char *p) { perror(p); exit(-1); } int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) do_cmd(argv[i]); /* once for each command-line arg */ exit(0); } do_cmd(char *cmd) /* execute and time the "cmd" */ { int status; clock_t start, end; struct tms tmsstart, tmsend; fprintf(stderr, "\ncommand: %s\n", cmd); if ( (start = times(&tmsstart)) == -1) /* starting values */ err_sys("times error"); if ( (status = system(cmd)) < 0) /* execute command */ err_sys("system() error"); if ( (end = times(&tmsend)) == -1) /* ending values */ err_sys("times error"); pr_times(end-start, &tmsstart, &tmsend); }

  47. 예제: times.c (2/3) APUE (Process Control) pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend) { static long clktck = 0; if(clktck == 0) clktck = sysconf(_SC_CLK_TCK); fprintf(stderr, " real: %7.2f\n", real / (double) clktck); fprintf(stderr, " user: %7.2f\n", (tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck); fprintf(stderr, " sys: %7.2f\n", (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck); fprintf(stderr, " child user: %7.2f\n", (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck); fprintf(stderr, " child sys: %7.2f\n", (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck); } • sysconf(_SC_CLK_TCK) ticks per second 값을 리턴함

  48. 예제: times.c (3/3) APUE (Process Control) • 실행 결과

More Related