Chinaunix首页 | 论坛 | 博客
  • 博客访问: 912437
  • 博文数量: 299
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2493
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-21 10:07
个人简介

Linux后台服务器编程。

文章分类

全部博文(299)

文章存档

2015年(2)

2014年(297)

分类: LINUX

2014-07-08 12:26:42

【waitpid()介绍】
waitpid主要用于根据进程ID号等待指定的子进程。函数形式如下:
******************************************************
pid_t waitpid(pid_t pid, int* status,int options);
******************************************************
关于options:
---WNOHANG:如果没有子进程执行,则返回
---WUNTRACED:当子进程处于停止状态,则立即返回
---WCONTINUED:当处于停止状态的子进程收到SIGCONT信号后接着运行返回(from Linux 2.6.10)
 
关于返回值:
---执行失败:返回-1;
---执行成功:返回状态status和状态改变的子进程ID;当options使用了WNOHANG参数且没有子进程的状态发生改变,则返回0.
 
用于检测退出状态的宏:
WIFEXITED(status):子进程正常退出情况下为true
WEXITSTATUS(status):当WIFEXITED为true的情况下,返回子进程的退出状态
WIFSIGNALED(status):子进程被信号终止返回true
WTERMSIG(status):当WIFSIGNALED为true的情况下,返回导致子进程终止的信号类型
WIFSTOPPED(status):当子进程接收到停止信号时true
WSTOPSIG(status):WIFSTOPPED为true时,返回导致子进程停止的信号类型
WIFCONTINUED(status):子进程接收到SIGCONT信号继续执行
 
【练习程序】
#include
#include
#include
#include
#include
int main(void)
{
 pid_t pid,wait_pid;
 int status;
 
 pid = fork();
 if(pid<0)
 {
  perror("Creat child process failed.\n");
  exit(1);
 }
 else if(pid==0)
 {
//对于子进程来说,打印自己的进程ID,这里pid是父进程创建它的时候返回值,对于子进程来说pid=0.要打印自己的PID,需要在子进程中重新调用getpid()
  printf("Creat child process ID: %ld.\n",(long)getpid());
  pause();
//这里用_exit()也应该是有目的的吧,因为子进程没有做任何修改与父进程共享的内存,也就是没有做复制,如果用exit退出,子进程退出会做关闭共享的文件,清空缓冲区等操作,可能对父进程造成影响。
  _exit(0);
 }
 else
 {
  //printf("Father process %ld.",(long)getpid());
//这里用do...while,里面的语句不止要执行一次,因为子进程可以用信号暂时stop,也可以continue,也可以以其他形式返回。而真正结束之前,父进程的waitpid都应该一直能执行。
  do
  {  
   wait_pid = waitpid(pid,&status,WUNTRACED|WCONTINUED);
   if(wait_pid == -1)
   {
    perror("Can't use waitpid function.\n");
    exit(0);
   }
   if(WIFEXITED(status))
   {
    printf("Child process exit,status is %d.\n",WEXITSTATUS(status));
   }
   if(WIFSIGNALED(status))
   {
    printf("Child process is killed by signal %d.\n",WTERMSIG(status));
   }
   if(WIFSTOPPED(status))
   {
    printf("Child process is stopped by signal %d.\n",WSTOPSIG(status));
   }
   if(WIFCONTINUED(status))
   {     
    printf("Child process continue to run......\n");
   } 
  }while(!WIFEXITED(status) || WIFSTOPPED(status));
 exit(0);  
 }
}
执行结果:


 gcc -o waitpid waitpid.c
 ./waitpid &     //后台执行
Creat child process ID: 5679.
[1] 5678
 ps
  PID TTY          TIME CMD
 5650 pts/0    00:00:00 bash
 5678 pts/0    00:00:00 waitpid   //父进程
 5679 pts/0    00:00:00 waitpid   //子进程
 5689 pts/0    00:00:00 ps

 kill -19 5679  //给子进程发送SIGSTOP信号
Child process is stopped by signal 19.
 kill -18 5679  //给子进程发送SIGCONT信号
Child process continue to run......
 kill -9 5679 //给子进程发送SIGKILL信号
Child process is killed by signal 9.
Can't use waitpid function.   //没有处理好?
: No child processes
[1]+  Done                  
 
 ps
  PID TTY          TIME CMD
 5650 pts/0    00:00:00 bash
 5689 pts/0    00:00:00 ps
阅读(1486) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

tianyashuibin2014-07-08 21:32:40

原因是当进程pid结束后,会在进程表中保存pid的退出状态,当waipid()之后,保存的退出状态信息就会销毁,所以再次waitpid()会出错。

tianyashuibin2014-07-08 21:30:57

经实验发现waitpid(pid, &status, *), 当pid进程退出后,第一次waitpid()会返回pid的退出状态,第二次waitpid()时会返回出错。