재 입 가능 과 재 입 불가

                    ,              ,     、                  。
                 ,                 FLOAT,                 
        
void fun()
{
//...     FLOAT       
}
       ,                 FLOAT    ,         ,               fun  ,        fun                FLOAT       ,         fun     ,       。

   fun     printf()  。

찬동
(전) 다시 들 어 갈 수 있 고 다시 들 어 갈 수 없습니다.
2011-10-04 21:38
이러한 상황 은 다 중 태 스 크 시스템 에 나타 나 작업 수행 기간 에 신 호 를 포착 하고 처리 할 때 프로 세 스 가 실행 중인 명령 시퀀스 가 신호 처리 프로그램 에 의 해 임시로 중단 된다.신호 처리 프로그램 에서 돌아 오 면 프로 세 스 정지점 의 정상 적 인 명령 순 서 를 계속 실행 합 니 다. 정지점 에서 다시 실행 하 는 과정 에서 함수 가 의존 하 는 환경 이 바 뀌 지 않 았 습 니 다. 이 함 수 는 다시 들 어 갈 수 있 고 반대로 다시 들 어 갈 수 없습니다.프로 세 스 가 중단 되 는 동안 시스템 은 프로 세 스 의 컨 텍스트 를 저장 하고 복원 하 는 것 으로 알려 져 있 습 니 다. 그러나 복 구 된 컨 텍스트 는 주소, cpu 레지스터 등 소량의 컨 텍스트 에 만 국한 되 고 함수 내부 에서 사용 되 는 전역 이나 정적 변수, buffer 등 은 보호 열 에 있 지 않 기 때문에 이 값 이 함수 가 중단 되 는 동안 변 경 될 경우.그러면 함수 가 정지점 으로 돌아 가 계속 실 행 될 때 그 결 과 는 예측 할 수 없다.예 를 들 어 malloc 는 하나의 프로 세 스 가 이때 malloc 할당 공간 을 실행 하고 있 는 것 과 같 습 니 다. 이때 프로그램 은 신호 가 중단 되 는 것 을 포착 하고 신호 처리 프로그램 에 도 malloc 가 있 습 니 다. 그러면 프로 세 스 의 환경 에 파 괴 를 초래 할 수 있 습 니 다. malloc 는 보통 분 배 된 저장 소 에 링크 표를 유지 하고 신호 처리 함 수 를 삽입 할 때프로 세 스 가 이 테이블 을 조작 하고 있 을 수도 있 습 니 다. 신호 처리 함수 의 호출 이 프로 세 스 의 조작 을 덮어 서 오류 가 발생 했 습 니 다.
다음 조건 중 하 나 를 만족 시 키 는 대부분 은 다시 들 어 갈 수 없 는 함수 입 니 다. (1) 정적 데이터 구 조 를 사 용 했 습 니 다.(2) malloc 또는 free 를 호출 했다.(3) 표준 I / O 함 수 를 호출 했다.표준 io 라 이브 러 리 는 다시 들 어 갈 수 없 는 방식 으로 전역 데이터 구 조 를 사용 하 는 경우 가 많다.(4) 부동 소수점 연산 을 진행 하 였 습 니 다. 많은 프로세서 / 컴 파일 러 에서 부동 소수점 은 일반적으로 다시 들 어 갈 수 없습니다 (부동 소수점 연산 은 대부분 협동 프로세서 나 소프트웨어 시 뮬 레이 션 을 사용 하여 이 루어 집 니 다.
1) 신호 처리 프로그램 A 내외 에서 같은 재 입 불가 함수 B 를 호출 했다.B 는 실행 하 는 동안 신호 에 의 해 끊 겨 A (A 에서 B 를 호출) 에 들 어 갔 고 일이 끝 난 후에 B 피 중단 점 으로 돌아 가 계속 실 행 했 습 니 다. 이때 B 함수 의 환경 이 바 뀔 수 있 고 그 결 과 는 예측 할 수 없 었 습 니 다.2) 다 중 스 레 드 는 프로 세 스 내부 의 자원 을 공유 합 니 다. 만약 에 두 스 레 드 A 가 같은 함수 F 를 호출 하면 A 스 레 드 가 F 에 들 어간 후에 스 레 드 스케줄 링 이 B 로 전환 되 고 B 도 F 를 실 행 했 습 니 다. 그러면 다시 스 레 드 A 로 전환 할 때 F 를 호출 한 결과 도 예측 할 수 없습니다.신호 처리 프로그램 에서 다시 들 어 갈 수 있 는 함 수 를 호출 하 더 라 도 문제 가 있 으 니 주의해 야 한다.일반적인 규칙 으로서 신호 처리 프로그램 에서 다시 들 어 갈 수 있 는 함 수 를 호출 할 때 그 전에 errno 를 저장 하고 그 후에 errno 를 복원 해 야 합 니 다.(스 레 드 마다 하나의 errno 변수 만 있 기 때문에 신호 처리 함수 가 그 값 을 수정 할 수 있 습 니 다. 자주 포착 되 는 신 호 는 SIGCHLD 입 니 다. 신호 처리 프로그램 은 보통 wait 함 수 를 호출 하고 각종 wait 함수 가 errno 를 바 꿀 수 있 습 니 다.)
다시 들 어 갈 수 있 는 함수 목록:
_exit()、 access()、alarm()、cfgetispeed()、cfgetospeed()、cfsetispeed()、cfsetospeed ()、chdir()、chmod()、chown()、close()、creat()、dup()、dup2()、execle()、 execve()、fcntl()、fork()、fpathconf ()、fstat()、fsync()、getegid()、 geteuid()、getgid()、getgroups()、getpgrp()、getpid()、getppid()、getuid()、 kill()、link()、lseek()、mkdir()、mkfifo()、 open()、pathconf()、pause()、pipe()、raise()、read()、rename()、rmdir()、setgid ()、setpgid()、setsid()、setuid()、 sigaction()、sigaddset()、sigdelset()、sigemptyset()、sigfillset()、 sigismember()、signal()、sigpending()、sigprocmask()、sigsuspend()、sleep()、 stat()、sysconf()、tcdrain()、tcflow()、tcflush()、tcgetattr()、tcgetpgrp()、 tcsendbreak()、tcsetattr()、tcsetpgrp()、time()、times()、 umask()、uname()、unlink()、utime()、wait()、waitpid()、write()。
책 에서 신호 처리 프로그램 에서 다시 들 어 갈 수 없 는 함 수 를 호출 하 는 예:
#include #include #include
static void func(int signo) {     struct passwd *rootptr;     if( ( rootptr = getpwnam( "root" ) ) == NULL )     {         err_sys( "getpwnam error" );     }     signal(SIGALRM,func);     alarm(1); }
int main(int argc, char** argv) {     signal(SIGALRM,func);     alarm(1);     for(;;)     {         if( ( ptr = getpwnam("sar") ) == NULL )         {             err_sys( "getpwnam error" );         }     }     return 0; }
signal 은 SIGALRM 을 설정 한 다음 에 타 이 머 를 설정 합 니 다. for 함수 가 실행 되 는 동안 getpwnam 함수 가 실행 되 는 동안 해당 신호 가 중단 되 고 신호 처리 함수 func 에 들 어가 서 func 를 실행 하 는 동안 alarm 에서 보 내 는 신 호 를 받 을 수 있 습 니 다. getpwnam 은 다시 중단 될 수 있 습 니 다. 그러면 예측 할 수 없 는 문제 가 발생 하기 쉽 습 니 다.
 
=================================================================================
다시 들 어 갈 수 없 는 함 수 는 되 돌아 오지 않 고 다시 호출 될 수 없습니다. 예 를 들 어 printf, malloc, free 등 은 다시 들 어 갈 수 없습니다. 중단 은 언제든지 발생 할 수 있 습 니 다. 예 를 들 어 printf 실행 과정 에서 중단 처리 함수 에서 printf 를 호출 할 수 없습니다. 그렇지 않 으 면 printf 가 다시 들 어 갈 것 입 니 다.  함수 가 대부분 다시 들 어 갈 수 없 는 것 은 함수 에서 전역 변 수 를 인 용 했 기 때 문 입 니 다. 예 를 들 어 printf 는 전역 변수 stdout, malloc, free 는 전역 메모리 할당 표를 참조 합 니 다.
개인 적 인 이해: 인 터 럽 트 가 발생 했 을 때 printf 로 실 행 될 때 인 터 럽 트 가 발생 했다 고 가정 합 니 다. 이때 stdout 자원 이 점용 되 었 기 때문에 두 번 째 인 터 럽 트 printf 는 첫 번 째 인 터 럽 트 된 stdout 자원 의 방출 을 기다 리 고 첫 번 째 인 터 럽 트 는 두 번 째 인 터 럽 트 가 되 돌아 오 기 를 기다 리 며 잠 금 을 만 들 었 습 니 다. 이렇게 이해 하 는 것 이 맞 는 지 모 르 겠 습 니 다.
 
 
다시 들 어 갈 수 없 는 함 수 는 이 함수 가 호출 이 끝나 기 전에 다시 호출 되 는 것 을 말 합 니 다. 다시 들 어 갈 수 있 는 함 수 는 이러한 문제 가 존재 하지 않 습 니 다. 다시 들 어 갈 수 없 는 함 수 는 실현 할 때 전역 자원 을 사용 합 니 다. 다 중 스 레 드 환경 에서 데이터 보호 와 상호 배척 접근 을 잘 처리 하지 않 으 면 오류 가 발생 합 니 다. 흔히 볼 수 있 는 다시 들 어 갈 수 없 는 것 입 니 다.함수: printf ---- 전역 변수 stdout malloc 인용 --- 전역 메모리 분배 표 free    --------전역 메모리 할당 표 는 유 닉 스에 서 보통 r 접 두 사 를 붙 인 동명 이인 으로 함수 버 전 을 다시 입력 할 수 있 습 니 다. 만약 그렇지 않다 면 예상 가능 한 오류 가 발생 한 곳 에 보호 잠 금 동기 화 메커니즘 등 을 시도 해 보 세 요.

좋은 웹페이지 즐겨찾기