voidshowStatus(int status){if(WIFEXITED(status)){printf("进程正常结束,返回值为:%d\n",WEXITSTATUS(status));}elseif(WIFSIGNALED(status)){printf("进程异常终止,终止信号为:%d\n",WTERMSIG(status));}}intmain(){pid_t ids[5];int i;for(i=0;i<5;i++){
ids[i]=fork();if(ids[i]==-1){perror("fork");return-1;}if(ids[i]==0){//子进程跳出循环break;}}if(i<5){//子进程printf("******我是子进程:%d, 是第%d个进程!\n",getpid(),i+1);sleep(i*10);printf("******我是子进程:%d, 我死了!\n",getpid());return i+1;}int status =0;for(i=0;;i++){pid_t inid =0;printf("[-1:任意一个子进程 0:同一个进程组的任意子进程 >0:指定子进程]:");scanf("%d",&inid);//pid_t id = waitpid(inid,&status,0); pid_t id =waitpid(inid,&status,WNOHANG);//非阻塞模式 //如果等待的子进程目前没有结束 直接返回if(id ==-1){--i;if(errno == ECHILD){//errno==ECHILD 表明没有子进程了printf("所有的子进程都已退出!\n");break;}continue;}elseif(id ==0){printf("等待的子进程没有结束!\n");}printf("有一个子进程:%d结束了,",id);showStatus(status);}return0;}
五、exec
exec函数族(系列函数)
int execl(const char *path,const char *arg,..);
path 执行的程序名(命令名)带路径的
arg,...: main函数参数列表 最后一个参数一定是NULL
int execlp(const char *file,const char *arg,...)
file 执行的程序名 如果不带路径,则从path环境变量中查找该程序
可以带路径
p:程序可以不带路径 从path环境变量指定的目录下查找
int execle(const char *path,const char *arg,...,char *const envp[ ])
e:带环境列表
l:传arg是用可变长参数列表
int execv(const char *path,char *const argv[ ])
v:传arg时用数组
int execvp(const char *file,char *const argv[])
int execvpe(const char *file,char *const argv[ ],char *const envp[ ] )
int execve(const char *filename,char *const argv[],char *const envp[])
exec一般不会单独使用 一般结合vfork来使用
intmain(){
函数名中没有p 程序必须带路径
l: 参数以可变参数列表形式传递
int ret =execl("/bin/ls","~","-l","-a",NULL);//excel创建一个新的进程替换掉当前进程int ret =execlp("ls","~","-l","-a",NULL);//命令可以不带路径 PATHint ret =execlp("/bin/ls","~","-l","-a",NULL);char* argv[]={"~","-l","-a",NULL};char* envp[]={"NAME=WD","AGE=18","PATH=/usr/bin:/bin/",NULL};
v: 参数列表用数组传递
int ret =execv("/bin/ls",argv);int ret =execvp("ls",argv);int ret =execle("test","test","a","b","123",NULL,envp);char* args[]={"test","name","afbc","123",NULL};int ret =execve("test",args,envp);int ret =execvpe("./test",args,envp);if(ret ==-1){perror("execl");return-1;}printf("main end!\n");//不会执行 exec函数会替换掉当前函数return0;}