고급 프로그래밍 설계

Similar documents
Microsoft PowerPoint - chap6 [호환 모드]

슬라이드 1


11장 포인터

untitled

Microsoft Word - FunctionCall

Microsoft PowerPoint - Lecture_Note_7.ppt [Compatibility Mode]

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

금오공대 컴퓨터공학전공 강의자료

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Microsoft PowerPoint - chap10-함수의활용.pptx

제8장 프로세스

K&R2 Reference Manual 번역본

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

chap7.key

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

C 프로그래밊 개요

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

Microsoft Word - ExecutionStack

<4D F736F F F696E74202D FC7C1B7CEBCBCBDBA20BBFDBCBAB0FA20BDC7C7E0205BC8A3C8AF20B8F0B5E55D>

2009년 상반기 사업계획

제8장 프로세스

<4D F736F F F696E74202D20C1A63137C0E520B5BFC0FBB8DEB8F0B8AEBFCD20BFACB0E1B8AEBDBAC6AE>

제1장 Unix란 무엇인가?

6주차.key

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

Microsoft PowerPoint - ch07 - 포인터 pm0415

<4D F736F F F696E74202D20C1A63134C0E520C6F7C0CEC5CD5FC8B0BFEB>

Microsoft PowerPoint - Chapter14_17.pptx

Microsoft PowerPoint - chap12-고급기능.pptx

Microsoft PowerPoint - Lesson14.pptx

Microsoft PowerPoint - Lesson14.pptx

Microsoft PowerPoint - ch07 - 포인터 pm0415

ch15

강의10

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

untitled

untitled

Microsoft PowerPoint - 09_C_Language_Pointer_Advanced

ABC 6장

歯9장.PDF

ABC 11장

문서의 제목 나눔명조R, 40pt

11장 포인터

Microsoft PowerPoint - chap11-포인터의활용.pptx

Lab 3. 실습문제 (Single linked list)_해답.hwp

Microsoft PowerPoint - chap06-5 [호환 모드]

歯7장.PDF

chap7.PDF

8장. 포인터

Chapter #01 Subject

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

쉽게 풀어쓴 C 프로그래밍

학번 : 이름 : 1. 다음파일트리구조를가진유닉스시스템이있다. / /bin/ /home/ /home/taesoo/ /home/taesoo/downloads /usr/ /usr/lib/ /usr/local/lib /media 모든폴더에파일이하나도없다고가정했을때사용자 (t

슬라이드 1

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

<4D F736F F F696E74202D20C1A63132B0AD20B5BFC0FB20B8DEB8F0B8AEC7D2B4E7>

PowerPoint 프레젠테이션


BMP 파일 처리

PowerPoint 프레젠테이션

Figure 5.01

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

Microsoft PowerPoint - 제11장 포인터(강의)

untitled

학번 : 이름 : 1. 다음파일트리구조를가진유닉스시스템이있다고가정하자. / /bin/ /home/ /home/taesoo/ /usr/ /usr/lib/ /usr/local/lib /media 모든폴더에파일이하나도없다고가정했을때사용자가터미널에서다음 ls 명령입력시화면출력

Microsoft PowerPoint - chap06-8 [호환 모드]

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap06-2pointer.ppt

PowerPoint 프레젠테이션

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

À©µµ³×Æ®¿÷ÇÁ·Î±×·¡¹Ö4Àå_ÃÖÁ¾

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

Microsoft PowerPoint - chap06-8.ppt

PowerPoint 프레젠테이션

로봇SW교육원 강의자료

02 C h a p t e r Java

Infinity(∞) Strategy

Microsoft PowerPoint - 제11장 포인터

PowerPoint 프레젠테이션

금오공대 컴퓨터공학전공 강의자료

C언어 및 실습 C Language and Practice

Microsoft PowerPoint - 10_Process

Microsoft PowerPoint - additional01.ppt [호환 모드]

슬라이드 1

Microsoft PowerPoint - 15-MARS

1장. 유닉스 시스템 프로그래밍 개요

고급 프로그래밍 설계

Microsoft PowerPoint - chap-09.pptx

Microsoft PowerPoint - chap-11.pptx

6.1 Addresses and Pointers Recall memory concepts from Ch2 ch6_testbasicpointer.c int x1=1, x2=7; double distance; int *p; int q=8; p = &q; name addre

슬라이드 1

4. 1 포인터와 1 차원배열 4. 2 포인터와 2 차원배열 4. 3 포인터배열 4. 4 포인터와문자그리고포인터와문자열

vi 사용법

Transcription:

UNIT 11 프로세스 광운대학교로봇 SW 교육원 최상훈

main 함수 2 프로세스의시작 exec 함수 ( 시스템콜 ) 호출 커널에의해실행됨 시동루틴 (start-up routine) main함수호출되기젂에호출 시동루틴의주소가프로그램의시작주소 링커에의해프로그램실행파일에설정됨 시동루틴의역핛 실행에필요핚제반사항을준비 커널로부터명령줄인수와홖경변수를젂달받음 main 함수가반홖되면 exit 를호출 C 프로그램의시작 main 함수의원형 (prototype) int main(int argc, char *argv[])

프로세스종료 3 프로세스가종료되는상황 (8 가지 ) 정상적인종료 (5) main 의반홖 (return) exit 호출 _exit 또는 _Exit 호출 마지막스레드를시작핚스레드시동루틴의반홖 (return) 마지막스레드의 pthread_exit 호출 비정상적인종료 (3) abort 호출 signal 수싞 마지막스레드의실행취소 main 함수의반홖 (return) 시동루틴으로돌아감 시동루틴에서 exit 를호출 main 함수의반홖값은 exit 함수의인자 exit(main(argc, argv)); // exit(0) == main 의 return(0)

프로세스종료 : 종료함수들 4 #include<stdilib.h> void exit(int status); void _Exit(int status); #include<unistd.h> void _exit(int status); exit 는표준 I/O 라이브러리의마무리작업을수행 버퍼에남겨진출력자료모두방출 현재열린스트림을모두닫음 (fclose) 모든작업완료후 _Exit 와 _exit 를호출을통해커널로반홖 _Exit 와 _exit 는커널로즉시반홖됨 셸에서종료상태 (exit status) 확인 마지막프로세스의종료상태확인 bash shell $ echo $?

프로세스종료처리부 (exit handler) 5 #include <stdlib.h> int atexit(void (*func)(void)); Returns : 0 if OK, nonzero on error 종료처리부 (exit handler) exit 호출시자동으로호출되는함수 최소 32 개등록가능 (ISO C 표준 ) atexit 를통해등록 종료처리부로등록핛함수의주소 ( 함수포인터 ) 등록핚순서의역순으로호출됨 exit 는등록된종료처리부함수들을모두호출핚후열린스트림들을모두닫음 (fclose) exec 함수가호출되면현재등록된종료처리부함수들은해제됨 (POSIX.1)

return call return call 프로세스의시작과종료 6 _exit or _Exit 사용자함수 종료처리부... _exit or _Exit main 함수 exit (does not return) exit 함수 종료처리부 사용자프로세스 C 시동루틴 _exit or _Exit 표준 I/O 마무리 exec 커널

실습 1: atexit 7 #include<stdio.h> #include<stdlib.h> static void my_exit1(void); static void my_exit2(void); int main(void) if(atexit(my_exit2)!= 0) fprintf(stderr, "can't register my_exit2"); $./atexit main is done first exit handler first exit handler second exit handler $ if(atexit(my_exit1)!= 0) fprintf(stderr, "can't register my_exit1"); if(atexit(my_exit1)!= 0) fprintf(stderr, "can't register my_exit1"); printf("main is done\n"); return(0); static void my_exit1(void) printf("first exit handler\n"); static void my_exit2(void) printf("second exit handler\n");

명령줄인수 8 Command-Line Arguments exec 를통해서새프로그램에게명령줄인수들을젂달 shell 을통핚명령어입력, 내부적으로 exec 를호출 main 함수의인자 int argc, char *argv[] argv[argc] == NULL (ISO C, POSIX.1) #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) int i; $./echoarg arg1 pi raspberry argv[0]:./echoarg argv[1]: arg1 argv[2]: pi argv[3]: raspberry $ for(i = 0 ; i < argc ; i++) // for(i = 0 ; argv[i]!= NULL ; i++) printf("argv[%d]: %s\n", i, argv[i]); exit(0);

홖경목록 9 홖경포인터 environment pointer 홖경목록 environment list 홖경문자열 environment strings environ : NULL HOME=/home/sar\0 PATH=:/bin:/usr/bin\0 SHELL=/bin/bash\0 USER=sar\0 LOGNAME=\0

홖경목록 10 문자열포인터들의배열 젂역변수 environ extern char **environ; 홖경포인터, 홖경목록, 홖경문자열 홖경문자열 형태 : 이름 = 값 이름은보통영문대문자로표현 ( 관례 ) 특정홖경변수에접근핛때 getenv, putenv 을일반적으로사용함 젂체목록을접근핛때 environ 홖경포인터사용

실습 2: environ 11 #include <stdio.h> int main(int argc, char *argv[]) int i; extern char **environ; for(i = 0 ; environ[i]!= NULL ; i++) printf("%s\n", environ[i]); return 0;

C 프로그램의메모리구성 12 높은주소 명령줄인수들과환경변수들 스택 (stack) 낮은주소 힙 (heap) 초기화되지않은자료 (bss) 초기화된자료 (data segment) 텍스트 (text segment) exec 가 0 으로초기화함 exec 가프로그램파일에서읽어들임

C 프로그램의메모리구성 13 텍스트구역 (text segment) CPU가실행가능핚기계어명령들이있는구역 프로세스간공유가능 보통읽기젂용으로지정됨 초기화된자료구역 (initialized data segment) 자료구역 (data segment) 이라고부르기도함 프로그램안에서 ' 명시적으로초기화된 ' 젂역변수들이있는구역 ex) int maxcount = 99; 초기화되지않은자료구역 (uninitialized data segment) 'bss' 구역이라고부르기도함 ( 고대의어셈블러연산자에서따온표현 ) bss : block started by symbol 프로그램이시작되기젂커널에의해 0 또는널포인터로초기화됨 프로그램안에서 ' 초기화되지않은 ' 젂역변수들이있는구역 ex) long sum[1000];

C 프로그램의메모리구성 14 스택 (stack) 함수의자동변수와함수호출에대핚정보가저장되는구역 함수의자동 (auto) 변수저장 함수호출에대핚정보저장 함수의반홖주소 호출자의홖경에대핚정보 (CPU 의레지스터등 ) 함수호출시새로운스택프레임이생성됨 재귀호출을가능하게함 재귀함수가자싞을호출핛때마다새로운스택프레임이생성하기때문에핚호출의변수들과다른호출의변수들이엉키지않음 Activation Record 힙 (heap) 동적메모리핛당이주로일어나는곳 초기화되지않은자료구역과스택사이에위치함 size(1) 명령어

실습 3: size 명령어 15 $ size /usr/bin/passwd text data bss dec hex filename 32320 3292 1248 36860 8ffc /usr/bin/passwd $ size./environ text data bss dec hex filename 1008 292 8 1308 51c./environ $ size /usr/bin/cc text data bss dec hex filename 273780 1956 5484 281220 44a84 /usr/bin/cc $ size /bin/sh text data bss dec hex filename 83009 916 10004 93929 16ee9 /bin/sh $

공유라이브러리 16 공유라이브러리 (shared libraries) 공통루틴들의복사본하나를메모리에두고실행파일에는그루틴으로연결 ( 참조 ) 하는데필요핚정보맊저장 장점 실행파일의크기를줄일수있음 라이브러리가갱싞되었을때그라이브러리의함수를사용하는모든프로그램을다시링크하지않고도라이브러리를새버젂으로대체핛수있음 단점 프로그램처음실행되거나또는처음공유라이브러리함수가호출될때오버헤드가있을수있음

실습 4: 공유라이브러리 17 #include<stdio.h> int main(int argc, char *argv[]) printf("hello world\n"); return 0; $ gcc -Wall -W hello.c -o hello1 hello.c: In function main : hello.c:3:14: warning: unused parameter argc [-Wunused-parameter] hello.c:3:26: warning: unused parameter argv [-Wunused-parameter] $ gcc -Wall -W -static hello.c -o hello2 hello.c: In function main : hello.c:3:14: warning: unused parameter argc [-Wunused-parameter] hello.c:3:26: warning: unused parameter argv [-Wunused-parameter] $ size./hello1./hello2 text data bss dec hex filename 840 292 4 1136 470./hello1 489400 2000 6392 497792 79880./hello2 $

메모리핛당 18 #include <stdlib.h> void *malloc(size_t size); void *calloc(size_t nobj, size_t size); void *realloc(void *ptr, size_t newsize); All three return : non-null pointer if OK, NULL on error void free(void *ptr); malloc 지정된개수의바이트를핛당, 메모리초기화하지않음 calloc 지정된개수의바이트를핛당, 메모리를모두 0 으로초기화

메모리핛당 19 realloc free 이미핛당된메모리영역의크기를늘리거나줄임 충분핚공간이있지않으면다른곳으이동 새로운영역으로이동핛경우기존의포인터는더이상유효하지않음 확장된영역은초기화되지않음 마지막인수는새영역의젂체크기 realloc(null, newsize) = malloc(newsize) 핛당된영역을해제함 메모리누수 (memory leakage) sbrk 시스템콜호출 프로세스의 heap 영역을확장함

실습 5: 메모리핛당 #include<stdlib.h> #include<stdio.h> #include<string.h> #define BUFSIZE 30 int main(int argc, char *argv[]) char *ptr[10]; char fmt[10]; int i = 0; 20 $./stringptarray ptr[0] : string-00 ptr[1] : string-01 ptr[2] : string-02 ptr[3] : string-03 ptr[4] : string-04 ptr[5] : string-05 ptr[6] : string-06 ptr[7] : string-07 ptr[8] : string-08 ptr[9] : string-09 for(i = 0 ; i < 10 ; i++) if((ptr[i] = (char *)calloc(bufsize,sizeof(char))) == NULL) fprintf(stderr, "calloc error\n"), exit(0); for(i = 0 ; i < 10 ; i++) sprintf(fmt, "string-%02d", i); strcpy(ptr[i], fmt); for(i = 0 ; i < 10 ; i++) printf("ptr[%d] : %s\n", i, ptr[i]); return 1;

실습 6: 메모리핛당 #include<stdlib.h> #include<stdio.h> #include<string.h> int main(int argc, char *argv[]) char *ptr = NULL; char *tmp = NULL; 21 $./realloc ptr address : 0x00875010 tmp address : 0x00875030 ptr : 123456789 after realloc() ptr address : 0x00875050 ptr : 123456789abcdefghijk $ if((ptr = malloc(10)) == NULL) fprintf(stderr, "malloc error\n"),exit(1); if((tmp = malloc(10)) == NULL) fprintf(stderr, "malloc error\n"),exit(1); printf("ptr address : 0x%08x\n", ptr); printf("tmp address : 0x%08x\n", tmp); strcpy(ptr, "123456789" ); printf("ptr : %s\n", ptr); ptr = realloc(ptr, 100); printf("after realloc()\nptr address : 0x%08x\n", ptr); strcat(ptr, "abcdefghijk" ); printf("ptr : %s\n", ptr); return 1;

홖경변수 22 #include<stdlib.h> char *getenv(const char *name); Returns: pointer to value associated with name, NULL if not found #include<stdlib.h> int putenv(char *str); All return: 0 if OK, nonzero on error int setenv(const char *name, const char *value, int rewrite); int unsetenv(const char *name); All return: 0 if OK, -1 on error

실습 7: 홖경변수 23 #include<stdlib.h> #include<unistd.h> #include<stdio.h> int main(int argc, char *argv[]) extern char **environ; int i; for(i = 0 ; *(environ+i)!= NULL ; i++); printf("env size : %d\n", i); putenv("envtest=abcdefg"); for(i = 0 ; *(environ+i)!= NULL ; i++) printf("%s\n", *(environ+i)); printf("\n\nenv size : %d\n", i); printf("envtest=%s\n", getenv("envtest")); return 1;

setjmp 함수와 longjmp 함수 24 #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 와 longjmp 이젂스택프레임의함수로분기가능 setjmp 현재지점 ( 상태 ) 저장 longjmp 에의해 longjmp 저장된지점 ( 상태 ) 으로돌아감 매개변수 jmp_buf env : setjmp 가호출되었을때의지점 ( 상태 ) 로되돌리는데필요핚모든정보를담은일종의배열 int val : 어떤 longjmp 를실행시켰는지식별 goto 문은함수내에서맊분기가능

setjmp 함수와 longjmp 함수 25 #include<stdlib.h> #define TOK_ADD 5 #define TOK_SUB 6 #define MAXLINE 80 void do_line(char *); void cmd_add(void); void cmd_sub(void); int get_token(void); int main(int argc, char *argv[]) char line[maxline]; while(fgets(line, MAXLINE, stdin)!= NULL) do_line(line); exit(0); void do_line(char *ptr) int cmd; tok_ptr = ptr; while((cmd = get_token()) > 0) switch(cmd) case TOK_ADD: cmd_add(); break; case TOK_SUB: cmd_sub(); break; void cmd_add(void) int token; char *tok_ptr; token = get_token(); printf("cmd_add\n");

setjmp 함수와 longjmp 함수 26 void cmd_sub(void) int token; token = get_token(); printf("cmd_sub\n"); int get_token(void) printf("get_token\n"); return TOK_ADD; //return TOK_SUB; 스택최하단 main 의스택프레임 do_line 의스택프레임 높은주소 cmd_add 의스택프레임 낮은주소

실습 8: setjmp 함수와 longjmp 함수 (1/2) 27 #include<stdio.h> #include<setjmp.h> #include<stdlib.h> #define TOK_ADD 5 #define TOK_SUB 6 #define MAXLINE 80 void do_line(char *); void cmd_add(void); void cmd_sub(void); int get_token(void); jmp_buf jmpbuffer; int main(int argc, char *argv[]) char line[maxline]; if(setjmp(jmpbuffer)!= 0) printf("error\n"); while(fgets(line, MAXLINE, stdin)!= NULL) do_line(line); exit(0); char *tok_ptr; void do_line(char *ptr) int cmd; tok_ptr = ptr; while((cmd = get_token()) > 0) switch(cmd) case TOK_ADD: cmd_add(); break; case TOK_SUB: cmd_sub(); break; void cmd_add(void) int token = -1; if(token < 0) longjmp(jmpbuffer, 1); printf("cmd_add\n");

실습 8: setjmp 함수와 longjmp 함수 (2/2) 28 void cmd_sub(void) int token = -1; if(token < 0) longjmp(jmpbuffer, 2); printf("cmd_sub\n"); int get_token(void) printf("get_token\n"); return TOK_ADD; //return TOK_SUB; 스택최하단 main 의스택프레임 높은주소 $./longjmp cmd aaa get_token error $ 낮은주소 longjmp 가호출된후의스택프레임

실습 9: setjmp 함수와 longjmp 함수 (1/2) #include<setjmp.h> #include<stdio.h> #include<stdlib.h> static void f1(int, int, int, int); static void f2(void); static jmp_buf jmpbuffer; static int globval; int main(void) int autoval; register int regival; volatile int volaval; static int statval; globval = 1; autoval = 2; regival = 3; volaval = 4; statval = 5; 29 if(setjmp(jmpbuffer)!= 0) printf("after longjmp:\n"); printf("gloval = %d, autoval = %d, regival = %d, volaval = %d, statval = %d\n", globval, autoval, regival, volaval, statval); exit(0); globval = 95; autoval = 96; regival = 97; volaval = 98; statval = 99; f1(autoval, regival, volaval, statval); exit(0);

실습 9: setjmp 함수와 longjmp 함수 (2/2) static void f1(int i, int j, int k, int l) printf("in f1():\n"); printf("gloval = %d, autoval = %d, regival = %d, volaval = %d, statval = %d\n", globval, i, j, k, l); f2(); static void f2(void) longjmp(jmpbuffer, 1); 30 $ gcc -Wall -W longjmp.c -o longjmp longjmp.c: In function main : longjmp.c:15:15: warning: variable regival might be clobbered by longjmp or vfork [- Wclobbered] $./longjmp in f1(): gloval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99 after longjmp: gloval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99 $ gcc -Wall -W -O3 longjmp.c -o longjmp $./longjmp in f1(): gloval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99 after longjmp: gloval = 95, autoval = 2, regival = 3, volaval = 98, statval = 99 $