깊이 연구:유 닉 스 다 중 프로 세 스 프로 그래 밍 wait()와 waitpid()함수

10355 단어 waitwaitpid
Wait 함수 와 waipid 함 수 는 프로 세 스 가 정상 적 이거 나 이상 하 게 종 료 될 때 커 널 은 부모 프로 세 스 가 SIGCHLD 신 호 를 보 내 는 것 과 같 습 니 다.하위 프로 세 스 가 하나의 이벤트 이기 때문에 이 신 호 는 커 널 계 의 부모 프로 세 스 가 보 내 는 비동기 알림 입 니 다.부모 프로 세 스 는 이 신 호 를 무시 하거나 이 신호 가 발생 할 때 호출 되 는 함 수 를 선택 할 수 있 습 니 다.이 신호 에 대한 시스템 기본 동작 은 무시 합 니 다.wait 나 waitpid 를 호출 하 는 프로 세 스 가 어떻게 될 지 알 아야 합 니 다.모든 하위 프로 세 스 가 실행 되 고 있 으 면 차단 합 니 다.하위 프로 세 스 가 종료 되 었 다 면 가 져 가 야 할 부모 프로 세 스 가 종료 상 태 를 가 져 오 면 이 하위 프로 세 스 의 종료 상 태 를 즉시 되 돌려 줍 니 다.만약 그 가 어떤 하위 프로 세 스 도 없다 면,즉시 오류 가 발생 하여 돌아 올 것 이다.프로 세 스 가 SIGCHLD 신 호 를 받 아 wait 를 호출 하면 wait 가 즉시 돌아 올 것 이 라 고 기대 할 수 있 습 니 다.그러나 임의의 시간 에 wait 를 호출 하면 프로 세 스 가 막 힐 수 있 습 니 다.두 함수 원형

#include <sys/wait.h>
pid_t wait(int *status);
pit_t wait(pid_t pid,int *status,int options);

, ID, -1;
다음은 간단 한 예 를 들 어 우리 wait 함수

#include "apue.h"
#include <sys/wait.h>

int main(void)
{
        pid_t pid1,pid2;
       printf("before fork
");

       if((pid1=fork())<0){
               printf("fork error");
        }else if(pid1==0){
                printf("child process 'spid=%d
",getpid());
                sleep(3);
        }else{
               pid2=wait(NULL);
               printf("wait process 's pid=%d
",pid2);
        }
        exit(0);
}
을 보 여 드 리 겠 습 니 다.
출력 결과:                              프로그램 이 실 행 될 때 마지막 줄 을 출력 할 때 3 초 를 기다 리 는 것 을 뚜렷하게 볼 수 있다.부모 프로 세 스 가 하위 프로 세 스 의 끝 을 기다 리 는 것 입 니 다.부모 프로 세 스 가 자식 프로 세 스 를 잡 고 wait 가 얻 을 결 과 를 얻 을 수 있 습 니 다.매개 변수 status:매개 변수 status 는 정형 지침 입 니 다.인자 status 의 값 이 NULL 이 아니라면 wait 는 하위 프로 세 스 가 종료 되 었 을 때의 상 태 를 꺼 내 서 저장 합 니 다.이것 은 전체 수치(int)입 니 다.하위 프로 세 스 가 정상적으로 종료 되 었 는 지 비정 상 으로 끝 났 는 지(한 프로 세 스 도 다른 프로 세 스 가 신호 로 끝 날 수 있 습 니 다.저 희 는 다음 글 에서 소개 합 니 다)와 정상 적 으로 끝 났 을 때의 반환 값 을 지적 합 니 다.어떤 신호 로 끝 났 는 지 등 정보.이러한 정 보 는 하나의 정수 가 다른 바 이 너 리 에 저장 되 어 있 기 때문에 일반적인 방법 으로 읽 는 것 이 매우 번 거 로 울 수 있 습 니 다.사람들 은 전문 적 인 매크로(macro)를 설계 하여 이 작업 을 완성 하 였 습 니 다.다음은 그 중에서 가장 자주 사용 하 는 두 가 지 를 배 워 보 겠 습 니 다.1.WIFEXITED(status)라 는 매크로 는 하위 프로 세 스 가 정상적으로 종료 되 었 는 지 여 부 를 지적 하 는 데 사 용 됩 니 다.만약 에...그것 은 0 이 아 닌 값 을 되 돌려 줍 니 다.이름 은 같 지만 여기 있 는 매개 변수 status 는 wait 의 유일한 매개 변수 인 정 수 를 가리 키 는 포인터 status 와 같 지 않 습 니 다.그 포인터 가 가리 키 는 정수 입 니 다.헷 갈 리 지 않도록 하 세 요.)2.WEXITSTATUS(status)는 WIFEXITED 가 0 이 아 닌 값 으로 돌아 갈 때 이 매크로 로 하위 프로 세 스 의 반환 값 을 추출 할 수 있 습 니 다.하위 프로 세 스 가 exit(5)를 호출 하면 WEXITSTATUS(status)는 5 로 돌아 갑 니 다.하위 프로 세 스 가 exit(7)를 호출 하면 WEXITSTATUS(status)는 7 을 되 돌려 줍 니 다.프로 세 스 가 정상적으로 종료 되 지 않 으 면 WIFEXITED 가 0 으로 돌아 가면 이 값 은 의미 가 없습니다.자세 한 책 에 있 는 표 아래 의 예 는 하위 프로 세 스 의 종료 신 호 를 가 져 오 는 것 입 니 다.그리고 출력 을 합 니 다.

#include "apue.h"
#include<sys/wait.h>
void pr_exit(int);
int main(void)
{
        pid_t pid;
        int status;
       if((pid=fork())<0){
               err_sys("fork error");
        }else if(pid==0){
                exit(7);
        }
       if(wait(&status)!=pid)
               err_sys("wait error");
        pr_exit(status);

       if((pid=fork())<0)
               err_sys("fork error");
        else if(pid==0)
        //      printf("child  pid=%d
",getpid());
                 //printf("child pid=%d
",getppid());
                abort();

        if(wait(&status)!=pid)
               err_sys("wait error");
        pr_exit(status);

       if((pid=fork())<0)
               err_sys("fork error");
        else if(pid==0)
               //printf(" parent pid=%d
",getppid());
                 //printf("child  pid=%d
",getpid());
                status/=0;
       if(wait(&status)!=pid)
               err_sys("wait error");                                                                                                                                      
       pr_exit(status);                                                                                                                                                    

        exit(0);                                                                                                                                                            
}                                                                                                                                                                           
void pr_exit(int status)                                                                                                                                                    
{                                                                                                                                                                            
       if(WIFEXITED(status))                                                                                                                                               
               printf("normal termination,exitstatus=%d
",WEXITSTATUS(status));                                                                                          
        elseif(WIFSIGNALED(status))                                                                                                                                        
               printf("abnormal termination,signalstatus=%d
",WTERMSIG(status),                                                                                          
#ifdef WCOREDUMP                                                                                                                                                            
                               WCOREDUMP(status)?"(core file generated)":"");                                                                                              
#else                                                                                                                                                                       
               "");                                                                                                                                                        
#endif                                                                                                                                                                      
        elseif(WIFSTOPPED(status))                                                                                                                                         
               printf("child stopped ,signal number=%d
",                                                                                                                 
                               WSTOPSIG(status));                                                                                                                           

출력 결과:
결과 에서 우 리 는 exit 를 정상 종료 함수 로 호출 하 는 것 을 보 았 다.Waitpid 함수.특정한 프로 세 스 의 함 수 를 기 다 려 야 할 때,우 리 는 이때 waitpid 함 수 를 사용 해 야 한다.위 에서 waitpid 함수 원형 을 보 았 을 때,우리 도 모두 pid 가 있다 는 것 을 알 게 되 었 다.t 매개 변수.설명 은 다음 과 같 습 니 다:Pid=-1,모든 하위 프로 세 스 를 기다 리 고 있 습 니 다.wait 와 같은 효과 가 있 습 니 다.Pid>0.프로 세 스 ID 와 pid 가 같은 하위 프로 세 스 를 기다 리 고 있 습 니 다.Pid==0 그룹 ID 를 기다 리 는 것 은 프로 세 스 그룹 ID 를 호출 하 는 모든 하위 프로 세 스 와 같 습 니 다.Pid<-1 그룹 ID 가 pid 의 절대 값 과 같은 하위 프로 세 스 를 기다 리 고 있 습 니 다.Waitpid 는 하위 프로 세 스 를 종료 하 는 프로 세 스 ID 를 되 돌려 줍 니 다.이 하위 프로 세 스 의 종료 상 태 를 status 가 가리 키 는 저장 장치 에 저장 합 니 다.Waitpid 함 수 는 wait 함수 가 제공 하지 않 은 세 가지 기능 을 제공 합 니 다.Waitpid 는 특정한 프로 세 스 를 기다 릴 수 있 으 며,wait 는 하위 프로 세 스 를 종료 하 는 상 태 를 되 돌려 줍 니 다.Waitpid 는 yigewait 요금 차단 버 전 을 제공 합 니 다.때때로 사용 자 는 하위 프로 세 스 의 상 태 를 얻 기 를 원 하지만 막 고 싶 지 않다.Waitpid 는 작업 제 어 를 지원 합 니 다.Waitpid 반환 값 과 오류 waitpid 의 반환 값 은 wait 보다 약간 복잡 합 니 다.모두 3 가지 상황 이 있 습 니 다.정상적으로 돌아 올 때 waitpid 는 수 집 된 하위 프로 세 스 의 프로 세 스 ID 를 되 돌려 줍 니 다.WNOHANG 옵션 을 설정 하고 호출 중 waitpid 에서 종료 한 하위 프로 세 스 가 수집 할 수 없 음 을 발견 하면 0 으로 돌아 갑 니 다.호출 중 오류 가 발생 하면-1 을 되 돌려 줍 니 다.이 때 errno 는 해당 하 는 값 으로 설정 되 어 오류 가 있 는 곳 을 표시 합 니 다.pid 가 가리 키 는 하위 프로 세 스 가 존재 하지 않 거나 이 프로 세 스 가 존재 하지만 프로 세 스 를 호출 하 는 하위 프로 세 스 가 아 닌 경우 waitpid 가 잘못 되 돌 아 옵 니 다.이 때 errno 는 ECHILD 로 설정 되 었 습 니 다.

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{       
         pid_tpc, pr;
         pc=fork();
         if(pc<0){  
                   /* fork */              
                   printf("Erroroccured on forking.
");     
         }elseif(pc==0){                  
                   /* */              
                   sleep(10);
                   /* 10 */            
         exit(0);    
         }       
         /* */     
         do{            
                   pr=waitpid(pc,NULL, WNOHANG);         
                   /* WNOHANG ,waitpid */                  
                   if(pr==0){                   
                   /* */                        
                            printf("Nochild exited
");                        
                   sleep(1); 
                   }
         }        while(pr==0);           
                   /* , */     
                   if(pr==pc)         
                            printf("successfullyget child %d
", pr);        
                   else          
                            printf("someerror occured
");
}
출력 결과:
 
결과 에서,우 리 는 부모 프로 세 스 가 하위 프로 세 스 의 끝 을 기다 리 고 있 는 것 을 보 았 다.

좋은 웹페이지 즐겨찾기