80 likes | 283 Views
예제 7-8 비지역분기 : setjmp,longjmp. 컴퓨터 정보학부 2005242134 최지은. 함수설명. setjmp 스택환경을 env 에 보존하여 후에 longjmp 에 사용할 수 있 게 한다 . longjmp 직전의 setjmp 를 호출하여 보존한 환경에 대응하는 env 인 수를 사용하여 복원한다 . longjmp 는 setjmp 가 0 을 반환하게 할 수 없다. 소스설명. #include<stdio.h> #include<stdlib.h> #include<signal.h>
E N D
예제 7-8비지역분기 : setjmp,longjmp 컴퓨터 정보학부 2005242134 최지은
함수설명 • setjmp 스택환경을 env에 보존하여 후에 longjmp에 사용할 수 있 게 한다. • longjmp 직전의 setjmp를 호출하여 보존한 환경에 대응하는 env 인 수를 사용하여 복원한다. • longjmp는 setjmp가 0을 반환하게 할 수 없다.
소스설명 #include<stdio.h> #include<stdlib.h> #include<signal.h> #include<setjmp.h> jmp_buf env1; main() { Int retcode, setjmp(); void ljmain(); { signal(SIGINT,ljmain); retcode = setjmp(env1); if(retcode !=0) printf(“\n Before loop \n”); // longjmp로 분기했을때만 메시지를 출력한다 while(1) menu(); } setjmp 함수에 의해 env1 에 현재 위치와 기타 정보가 저장 된다 인터럽트 시그널이 들어오면 ljmain 루틴을 호출한다 setjmp 함수는 처음 호출 될때는 리턴값 (retcode에 들어가는값) 이 0이지만 두번째 혹은 그 이후에는 longjmp 의 두번째 인자값이 setjmp 의 리턴값이 된다
소스설명 menu() { char resp[2]; prompt: printf(“cmd: ”); scanf(“%s”,resp); switch(resp[0]) { case ‘s’ : sfn(); break; case ‘t’ : tfn(); break; case ‘q’ : exit(0); default : printf(“?\n”); goto prompt; } } 메뉴를 입력받아 처리 루틴으로 분기한다
소스설명 void ljmain() { void longjmp(); signal(SIGINT,ljmain); printf(“\n INTERUPTED \n”); longjmp(env1,1); } sfn() { int i, i=0; for(i=0; ;i++) { printf(“%d \t”,i*i); sleep(1); if(++j %8 == 0) printf(“\n”); } } 인터럽트 신호가 수신되었을 때 실행되며, 신호를 재 설정하고 인터럽트 신호가 수신된 메시지를 출력한후 setjmp로 설정된 위치로 longjmp한다. For루프를 이용하여 임의의 정수의 값을 출력
소스설명 Time과 ctime 함수를 호출하여 시간과 날짜를 출력 tfn() { long now, time(); char *ctime(); (void) time(&now); printf(“%s”,ctime(&now)); }
실행결과 cmd: s 0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 ^c cmd: q
소스의 문제점? longjmp 인터럽트가 다 안 끝났는데 또 인터럽트를 요청하니까 끝나기 전에 longjmp 때문에 다른 곳으로 가기 때문에 한번밖에 실행되지 않는다