Upload
gilon
View
75
Download
0
Embed Size (px)
DESCRIPTION
Linux/UNIX Programming APUE (Process Control) [Ch. 8] 최 미 정 강원대학교 컴퓨터과학전공. 강의 내용. APUE (Process Control). 프로세스 ID 프로세스 생성 프로세스 종료 레이스 컨디션 프로그램 실행 기타. Process Identifiers (1/2). APUE (Process Control). - PowerPoint PPT Presentation
Citation preview
Linux/UNIX ProgrammingLinux/UNIX Programming
APUE (Process Control) [Ch. APUE (Process Control) [Ch. 8]8]
최 미 정최 미 정강원대학교 컴퓨터과학전공강원대학교 컴퓨터과학전공
UNIX System ProgrammingPage 2
강의 내용강의 내용
프로세스 ID
프로세스 생성
프로세스 종료
레이스 컨디션
프로그램 실행
기타
APUE (Process Control)
UNIX System ProgrammingPage 3
Process Identifiers (1/2)Process Identifiers (1/2)
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
APUE (Process Control)
UNIX System ProgrammingPage 4
Process Identifiers (2/2)Process Identifiers (2/2)
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
APUE (Process Control)
UNIX System ProgrammingPage 5
System Process System Process 예제예제APUE (Process Control)
UNIX System ProgrammingPage 6
PID PID 관련 함수관련 함수
None of these functions has an error return.
APUE (Process Control)
#include <sys/types.h>#include <unistd.h>
pid_t getpid(void); // returns process IDpid_t getppid(void); // returns parent process IDuid_t getuid(void); // returns real user IDuid_t geteuid(void); // returns effective user IDgid_t getgid(void); // returns real group IDgid_t getegid(void); // returns effective group ID
UNIX System ProgrammingPage 7
강의 내용강의 내용
프로세스 ID
프로세스 생성
프로세스 종료
레이스 컨디션
프로그램 실행
기타
APUE (Process Control)
UNIX System ProgrammingPage 8
fork() (1/3)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.
UNIX System ProgrammingPage 9
fork() (2/3)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 instructions
following the fork() call
Often, fork() is followed by exec().
UNIX System ProgrammingPage 10
fork() (3/3)fork() (3/3)APUE (Process Control)
main() {...rtn = fork();...}
DATA
STACK
USER AREA
TEXT
main() {...rtn = fork();...}
DATA
STACK
USER AREA
TEXT
main() {...rtn = fork();...}
DATA
STACK
USER AREA
TEXT
BEFORE fork()
AFTER fork()
pid: 12791
pid: 12791 pid: 12793
UNIX System ProgrammingPage 11
예제예제 : fork.c (1/2): fork.c (1/2)
#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);}
APUE (Process Control)
UNIX System ProgrammingPage 12
예제예제 : fork.c (2/2): fork.c (2/2)APUE (Process Control)
실행 결과
UNIX System ProgrammingPage 13
File Sharing after fork()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.
parent process table entry
file descriptorsfd 0:fd 1:fd 2:
. . . .
fd flags ptr
file tablefd status flagscurrent file offsetv-node ptr
fd status flagscurrent file offsetv-node ptr
v-node tablev-node
information
i-nodeinformation
current file size
file descriptorsfd 0:fd 1:fd 2:
. . . .
fd flags ptr
child process table entry fd status flags
current file offsetv-node ptr
v-nodeinformation
i-nodeinformation
current file size
v-nodeinformation
i-nodeinformation
current file size
UNIX System ProgrammingPage 14
Properties Inherited to the Properties Inherited to the ChildChild
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
APUE (Process Control)
UNIX System ProgrammingPage 15
Properties NOT Inherited to the Properties NOT Inherited to the ChildChild
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
APUE (Process Control)
UNIX System ProgrammingPage 16
강의 내용강의 내용
프로세스 ID
프로세스 생성
프로세스 종료
레이스 컨디션
프로그램 실행
기타
APUE (Process Control)
UNIX System ProgrammingPage 17
exit() – Process Terminationexit() – Process Termination
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
APUE (Process Control)
UNIX System ProgrammingPage 18
exit() – Termination Statusexit() – Termination Status
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
APUE (Process Control)
UNIX System ProgrammingPage 19
exit() – Child Termination exit() – Child Termination skipskip
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() 해 주어야 함
APUE (Process Control)
UNIX System ProgrammingPage 20
wait(), waitpid() (1/2)wait(), waitpid() (1/2)
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.
• ( 무사히 , 죽을 수 있도록 배려 ~)
APUE (Process Control)
UNIX System ProgrammingPage 21
wait(), waitpid() (2/2)wait(), waitpid() (2/2)
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()
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
UNIX System ProgrammingPage 22
Macros to examine the termination status Macros to examine the termination status skipskip
APUE (Process Control)
Macro Description
WIFEXITED(status)True if child is terminated normallyWEXITSATUS(status) : get exit status (low-order 8 bits)
WIFSIGNALED(status)
True if child is terminated abnormally (by receipt of a signal)WTERMSIG(status): fetch the signal number that caused the termination.
WIFSTOPPED(status)
True if child is currently stoppedWSTOPSIG(status): fetch the signal number that caused the stop.
UNIX System ProgrammingPage 23
예제예제 : nwait.c (1/3) : nwait.c (1/3) skip skip
#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));
}
APUE (Process Control)
UNIX System ProgrammingPage 24
예제예제 : nwait.c (2/3) : nwait.c (2/3) skip skip
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);}
APUE (Process Control)
UNIX System ProgrammingPage 25
예제예제 : nwait.c (3/3) : nwait.c (3/3) skip skipAPUE (Process Control)
실행 결과
UNIX System ProgrammingPage 26
강의 내용강의 내용
프로세스 ID
프로세스 생성
프로세스 종료
레이스 컨디션
프로그램 실행
기타
APUE (Process Control)
UNIX System ProgrammingPage 27
Race Conditions (1/2)Race Conditions (1/2)
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
APUE (Process Control)
UNIX System ProgrammingPage 28
Race Conditions (2/2)Race Conditions (2/2)
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
APUE (Process Control)
UNIX System ProgrammingPage 29
예제예제 : race.c (1/2): race.c (1/2)
#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); }}
APUE (Process Control)
UNIX System ProgrammingPage 30
예제예제 : race.c (2/2): race.c (2/2)APUE (Process Control)
실행 결과
UNIX System ProgrammingPage 31
How to Avoid Race Condition?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)
UNIX System ProgrammingPage 32
강의 내용강의 내용
프로세스 ID
프로세스 생성
프로세스 종료
레이스 컨디션
프로그램 실행
기타
APUE (Process Control)
UNIX System ProgrammingPage 33
Program Execution: exec() Program Execution: exec() (1/2)(1/2)
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() 를 호출하여 완전히 다른 프로그램으로 실행된다 .
APUE (Process Control)
#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.outexecute /bin/echo
UNIX System ProgrammingPage 34
Program Execution: exec() Program Execution: exec() (2/2)(2/2)
APUE (Process Control)
main() {...execl("newpgm", ...);...}
DATA
STACK
USER AREA
CODE
main() {
...
}
DATA
STACK
USER AREA
CODE
BEFORE exec()pid: 12791 pid: 12791
AFTER exec()
/*newpgm*/
UNIX System ProgrammingPage 35
exec() Functionsexec() FunctionsAPUE (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
UNIX System ProgrammingPage 36
Properties inherited to the new Properties inherited to the new programprogram
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, …
APUE (Process Control)
UNIX System ProgrammingPage 37
예제예제 : nexec.c, echoall.c (1/3): nexec.c, echoall.c (1/3)
#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);}
APUE (Process Control)
UNIX System ProgrammingPage 38
예제예제 : nexec.c, echoall.c (2/3): nexec.c, echoall.c (2/3)
#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);}
APUE (Process Control)
UNIX System ProgrammingPage 39
APUE (Process Control)
실행 결과
예제예제 : nexec.c, echoall.c (3/3): nexec.c, echoall.c (3/3)
UNIX System ProgrammingPage 40
강의 내용강의 내용
프로세스 ID
프로세스 생성
프로세스 종료
레이스 컨디션
프로그램 실행
기타
APUE (Process Control)
UNIX System ProgrammingPage 41
system()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
UNIX System ProgrammingPage 42
예제예제 : system.c: system.c
#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);}
APUE (Process Control)
UNIX System ProgrammingPage 43
예제예제 : myls.c (1/2): myls.c (1/2)
#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);}
APUE (Process Control)
UNIX System ProgrammingPage 44
예제예제 : myls.c (2/2): myls.c (2/2)APUE (Process Control)
실행 결과
UNIX System ProgrammingPage 45
Process TimesProcess TimesAPUE (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 를 점유한 시간 )
UNIX System ProgrammingPage 46
예제예제 : times.c (1/3): times.c (1/3)
#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);}
APUE (Process Control)
UNIX System ProgrammingPage 47
예제예제 : times.c (2/3): times.c (2/3)
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);}
APUE (Process Control)
sysconf(_SC_CLK_TCK) ticks per second 값을 리턴함
UNIX System ProgrammingPage 48
예제예제 : times.c (3/3): times.c (3/3)APUE (Process Control)
실행 결과