제 6 장프로세스 (Process) 숙대창병모 1
내용 프로세스시작 / 종료 명령중인수 / 환경변수 메모리배치 / 할당 비지역점프 숙대창병모 2
프로세스시작 / 종료 숙대창병모 3
Process Start Kernel exec system call user process Cstart-up routine call return int main(int argc, char * argv[]); 숙대창병모 4
main() int main(int argc, char *argv[]); argc : the number of command-line arguments argv[] : an array of pointers to the arguments Cstart-up routine Started by the kernel (by the exec system call) Take the command-line arguments and the environment from the kernel Call main exit( main( argc, argv) ); 숙대창병모 5
Process Termination Normal termination return from main() calling exit() i() : calling _exit() Abnormal termination calling abort() terminated by a signal 숙대창병모 6
exit() #include <stdlib.h> void exit(int status); 프로세스를정상적으로종료한다 cleanup processing 을수행한다 모든열려진스트림을닫고 (fclose) 출력버퍼의내용을디스크에쓴다 (fflush) status the exit status of a process 이값은 UNIX shell 에의해서사용됨 숙대창병모 7
_exit() #include <unistd.h> void _exit(int status); 프로세스를정상적으로종료한다 커널로즉시리턴한다 숙대창병모 8
atexit() #include <stdlib.h> void atexit(void (*func)(void)); returns: 0 if OK, nonzero on error exit handler 를등록한다 프로세스당 32 개까지 func an exit handler a function pointer exit() 는 exit handler 들을등록된역순으로호출한다 숙대창병모 9
C Program Start and Termination _exit user function return call _exit main exit exit (does not return) function function return call C start-up routine _exit exit handler exit handler standard I/O cleanup user process exec kernel 숙대창병모 10
Example of exit handlers /* doatexit.c */ static void my_exit1(void), my_exit2(void); int main(void) { if (atexit(my_exit2) exit2)!= 0) perror("can't register my_exit2 exit2"); if (atexit(my_exit1)!= 0) perror("can't register my_exit1"); if (atexit(my_exit1)!= 0) perror("can't register my_exit1"); printf("main is done\n"); return 0; } static void my_exit1(void) { printf("first first exit handler\n"); } static void my_exit2(void) { printf("second exit handler\n"); } 숙대창병모 11
명령줄인수 / 환경변수 숙대창병모 12
Command-Line Arguments exec() pass command-line arguments to a new program argv[0], argv[1],, argv[argc-1] argv[argc] ]is NULL (ANSI, POSIX.1) argv argument list argv[0] argv[1] argv[argc-1] NULL arguments program 이름 1st argument (argc-1)th argument 숙대창병모 13
Echo command-line arguments #include "ourhdr.h h" /* echoarg.c c */ int main(int argc, char *argv[]) { int i; for (i = 0; i < argc; i++) /* echo all command-line args */ printf("argv[%d]: %s\n", i, argv[i]); exit(0); } #include "ourhdr.h" /* echoarg1.c */ int main(int argc, char *argv[]) { int i = 0; char **p =argv; while (*p) printf("argv[%d]: %s\n", i++, *p++); exit(0); } 숙대창병모 14
Environment Variables 환경변수 (environment variable) 부모프로세스에서자식프로세스로전달된다.login 또는.cshrc 파일에서환경변수를설정한다. 환경변수 : 이름 = 값 $env USER=lsj LOGNAME=lsj HOME=/user1/lsj PATH=/bin:/usr/bin:/usr/local/bin:/usr/ccs/bin:/usr/ucb:/usr/open win/bin:/etc:. MAIL=/var/mail/lsj SHELL=/bin/csh 숙대창병모 15
Environment List 전역변수 environ 을이용하여환경변수에접근한다. extern char ** environ; 각항목은 " 환경변수이름 = 값 " 의형식 각문자열은 '\0' 로끝난다 환경변수리스트의마지막은 NULL 포인터 argv 와같은구조 숙대창병모 16
Environment List environment pointer environ environment list... NULL environment strings "USER=chang" " "LOGNAME=chang" "HOME=/user/chang" "PATH=/bin:/usr/local " "MAIL =/var/mail/chang" "SHELL=/bin/csh" 숙대창병모 17
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); 숙대창병모 18
getenv() #include <stdlib.h> char *getenv(const char *name); Returns : pointer to value associated with name, NULL if not found 환경변수리스트에서이름이 name 인것을찾아 값에대한포인터를리턴한다 실패하면 NULL 포인터를리턴 숙대창병모 19
putenv() #include <stdlib.h> int putenv(const char *str); Returns: 0 if OK, nonzero on error 환경변수를추가한다 str 은 "name=value" 형식의문자열 성공적으로실행된경우 0 을리턴 같은이름의환경변수가이미있다면새값으로변경된다 숙대창병모 20
setenv() unsetenv() #include <stdlib.h> int setenv(const char *name, const char *value, int rewrite); Returns: 0 if OK, nonzero on error void unsetenv(const char *name); setenv 는환경변수name = value 을등록한다 name 의환경변수가이미있을경우 rewrite!= 0 이면새값으로변경되고 rewrite == 0 이면값이변경되지않는다 unsetenv 는환경변수 name 을제거한다 숙대창병모 21
메모리배치 / 할당 숙대창병모 22
Memory Layout of a C program high address stack command-line arguments and environment variables low address heap uninitialized data (bss) initialized data Text(code) initialized to zero by exec read from program file by exec 숙대창병모 23
Memory Layout of a C program Text(code) segment Machine instructions (read-only, sharable) Initialized i data segment e.g. int maxcount = 99; (initialized) Uninitialized iti data segment (bss: block started by symbol) eg e.g. long sum[1000]; Stack automatic local variables, temporary variables, return address, caller's environment (registers) Heap dynamic memory allocation 숙대창병모 24
Memory Allocation #include <stdlib.h> void *malloc(size_t size); void *calloc(size_t nobj, size_t size); void *realloc(void *ptr, size_t newsize); returns : nonnull pointer if OK, NULL on error void free(void *ptr); dynamic allocation of memory from heap provide suitable alignment ex) doubles must start at the addresses that are multiples of 8 library manages memory pool 숙대창병모 25
Memory Allocation malloc() allocates specified number of bytes, initial value of memory is indeterminate calloc() allocates specified number of objects of specified size, initialized to all 0 bits realloc() changes size of previously allocated memory, initial value of new area is indeterminate 숙대창병모 26
비지역점프 (Nonlocal jumps) 숙대창병모 27
Nonlocal l Jumps:setjmp/longjmpj / j Transfer control to an arbitrary location. Direct nonlocal goto: setjmp/longjmp a way to break the procedure call/return discipline Useful for error/exception recovery and signal handling int setjmp(jmp_buf env) Must be called before longjmp Identifies a return site for a subsequent longjmp. Called once, returns one or more times void longjmp(jmp_buf env, int val) Called after setjmp Nonlocal l goto the return site set by setjmp Called once, but never returns 숙대창병모 28
setjmp(), longjmp() #include <setjmp.h> int setjmp(jmp_buf env); returns : 0 if called directly, nonzero if returning from a call to longjmp void longjmp(jmp_buf env,int val); setjmp store information at env for return to setjmp point returns 0 if called directly returns nonzero(val) if returning from a call to longjmp longjmp use env to jump to setjmp point and val as a return value. Several longjmp can use the same setjmp location with different val. normally env is a global variable since it can be referenced from another function. 숙대창병모 29
setjmp/longjmp / j Example #include <setjmp.h> jmp_buf buf; main() { if (setjmp(buf)!= 0) { printf("back in main due to an error\n"); exit(0); } else printf("first first time through\n"); p1(); /* p1 calls p2, which calls p3 */ }... p3() { <error checking code> if (error) longjmp(buf, 1) } 숙대창병모 30
Limitations i i of Nonlocal l Jumps Works within stack discipline Can only long jump to environment of function that has been called but not yet completed jmp_buf env; env P1() { if (setjmp(env)) { /* Long Jump to here */ } else { P2(); } } P2() {... P2();... P3(); } P3() { longjmp(env, 1); } P1 P2 P2 P2 P3 Before longjmp P1 After longjmp 숙대창병모 31
결과 : testjmp.c #include <setjmp.h> /* testjmp.c */ static void f1(int, int, int); static void f2(void); static jmp_buf jmpbuffer; int main(void) { int count; register int val; volatile int sum; } count = 2; val = 3; sum = 4; if (setjmp(jmpbuffer)!= 0) { printf("after longjmp: count = %d, val = %d, sum = %d\n", count, val, sum); exit(0); } count = 97; val = 98; sum = 99; /* changed after setjmp, before longjmp */ f1(count, val, sum); /* never returns */ static void f1(int i, int j, int k) { printf("in f1(): count = %d, val = %d, sum = %d\n", i, j, k); f2(); } static void f2(void) { longjmp(jmpbuffer, 1); } 숙대창병모 32
Results: testjmp.c $ cc testjmp.c $ a.out in f1(): count = 97, val = 98, sum = 99 after longjmp: count = 97, val = 98, sum = 99 $ cc O testjmp.c $ a.out in f1(): count = 97, val = 98, sum = 99 after longjmp: count=2, val=3, sum=99 숙대창병모 33