Sunday, September 14, 2014

Unix Prog: Wait for Process -- waitid, wait3, wait4

1. waitid

System Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/sys/wait.h  
 ......  
 /* Wait for a childing matching IDTYPE and ID to change the status and  
   place appropriate information in *INFOP.  
   If IDTYPE is P_PID, match any process whose process ID is ID.  
   If IDTYPE is P_PGID, match any process whose process group is ID.  
   If IDTYPE is P_ALL, match any process.  
   If the WNOHANG bit is set in OPTIONS, and that child  
   is not already dead, clear *INFOP and return 0. If successful, store  
   exit code and status in *INFOP.  
   
   This function is a cancellation point and therefore not marked with  
   __THROW. */  
 extern int waitid (idtype_t __idtype, __id_t __id, siginfo_t *__infop,  
           int __options);  
 ......  
 ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/bits/waitflags.h  
 ......  
 /* Bits in the third argument to `waitpid'. */  
 #define WNOHANG     1    /* Don't block waiting. */  
 #define WUNTRACED    2    /* Report status of stopped children. */  
 ......  
 /* Bits in the fourth argument to `waitid'. */  
 #define WSTOPPED    2    /* Report stopped child (same as WUNTRACED). */  
 #define WEXITED     4    /* Report dead child. */  
 #define WCONTINUED   8    /* Report continued child. */  
 #define WNOWAIT     0x01000000 /* Don't reap, just poll status. */  
 ......  
 #define __WNOTHREAD   0x20000000 /* Don't wait on children of other threads  
                    in this group */  
 #define __WALL     0x40000000 /* Wait for any child. */  
 #define __WCLONE    0x80000000 /* Wait for cloned process. */  
 ......  
 typedef enum  
 {  
  P_ALL,        /* Wait for any child. */  
  P_PID,        /* Wait for specified process. */  
  P_PGID        /* Wait for members of process group. */  
 } idtype_t;  
 ......  

proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<sys/wait.h>  
   
 int main(int argc, char* argv[])  
 {  
  pid_t pid;  
   
  if((pid = fork()) < 0) {  
   printf("fork error!\n");  
   exit(1);  
  }  
  else if(pid == 0) {  
   printf("child process output!\n");  
   sleep(2);  
   exit(0);  
  }  
   
  siginfo_t infop;  
  if(waitid(P_PID, pid, &infop, WEXITED) < 0) {  
   printf("waitid error!\n");  
   exit(1);  
  }  
   
  printf("child terminated. parent process output!\n");  
  exit(0);  
 }  

shell:
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 child process output!  
 child terminated. parent process output!  

2. wait3 and wait4

The difference of wait3 and wait4 is: it provides the argument "struct rusage" to return the resource usage information for this process.

System Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/sys/wait.h  
 ......  
 /* Wait for a child to exit. When one does, put its status in *STAT_LOC and  
   return its process ID. For errors return (pid_t) -1. If USAGE is not  
   nil, store information about the child's resource usage there. If the  
   WUNTRACED bit is set in OPTIONS, return status for stopped children;  
   otherwise don't. */  
 extern __pid_t wait3 (__WAIT_STATUS __stat_loc, int __options,  
            struct rusage * __usage) __THROWNL;  
 #endif  
   
 #ifdef __USE_BSD  
 /* PID is like waitpid. Other args are like wait3. */  
 extern __pid_t wait4 (__pid_t __pid, __WAIT_STATUS __stat_loc, int __options,  
            struct rusage *__usage) __THROWNL;  
 ......  

proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<sys/wait.h>  
 #include<sys/resource.h>  
   
 int main(int argc, char* argv[])  
 {  
  pid_t pid;  
   
  if((pid = fork()) < 0) {  
   printf("fork error!\n");  
   exit(1);  
  }  
  else if(pid == 0) {  
   printf("child process output!\n");  
   sleep(2);  
   exit(0);  
  }  
   
  struct rusage use;  
  int status;  
  if(wait4(pid, &status, 0, &use) < 0) {  
   printf("wait4 error!\n");  
   exit(1);  
  }  
   
  printf("child terminated. parent process output!\n");  
  exit(0);  
 }  

shell:
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 child process output!  
 child terminated. parent process output!  

No comments:

Post a Comment