赞
踩
(1)代码运行完毕,结果正确 退出码为0
(2)代码运行完毕,结果不正确 退出码非0
(3)代码异常终止 程序崩溃,退出码无意义
(1)正常终止:
(2)异常退出
#include<stdio.h>
int main(){
printf("return 12\n");
return 12;
}
12是进程myproc的退出码(main函数的返回值 )
0是第一条echo的退出码
函数返回
参数:退出码
—————————————————————————————————————
父进程通过wait/waitpid等待子进程退出
为何让父进程等待?
1.通过获取子进程退出的信息,得到子进程执行的结果
2.可以保证:时序问题,子进程先于父进程退出
3.子进程退出,父进程不管不顾,可能进入僵尸状态,造成内存泄漏,需要通过父进程wait释放子进程占用的资源
通过stat_loc可以获取子进程退出的信息:
正常退出:第8-15位是子进程退出码,0-7位是退出信号(正常退出则为0)
被信号所杀:第0-6位是终止信号,第七位是core dump标志,不使用8-15
#include <stdio.h> #include <sys/types.h> //wait #include <sys/wait.h> // wait #include <stdlib.h> // exit #include <unistd.h> // fork //进程等待 wait //子进程运行5s,父进程sleep10s,后5s子进程成为僵尸进程 //10s后父进程执行wait,回收子进程 int main(){ pid_t pid = fork(); if(pid == 0){ int cnt = 3; while(cnt){ printf("child[%d] is running,cnt = %d\n",getpid(),cnt); cnt--; sleep(1); } // 浮点型错误,退出信号=8 //int a = 10; //a/=0; exit(11); } sleep(5); //pid_t ret = wait(NULL);// 返回等待的子进程pid或-1,参数是退出码 //pid_t ret = waitpid(pid,NULL,0);// 返回值同上,pid设成1时等待任意一个子进程 int status = 0; pid_t ret = waitpid(pid,&status,0); if(ret>0){ // //printf("father wait:%d,status exit code:%d,status exit signal:%d\n",ret,(status>>8),status); //printf("father wait:%d,status exit code:%d,status exit signal:%d\n",ret,(status>>8)&0xFF,status&0x7F); if(WIFEXITED(status)){// 没有收到退出信号 // 正常结束的 获取对应退出码 printf("exit code:%d\n",WEXITSTATUS(status)); }else{ printf("error,get a signal\n"); } }else{ printf("father failed\n"); } return 0; }
进程的等待方式:
(1)阻塞等待:
阻塞的本质是进程的PCB被放入等待队列,并将进程的状态修改为S状态
返回的本质是进程的PCB从等待队列拿到R队列,从而被CPU调度
waitpid(-1,&sataus,0);
(2)非阻塞等待
不断调度父进程
基于非阻塞的轮询等待方案
int ret = waitpid(-1,&sataus,WNOHANG);// WNOHANG:不阻塞模式
if(ret == 0){
//子进程没有退出,但是waitpid等待是成功的,需要父进程重复进行等待
}else if(ret > 0){
// 子进程退出了,waitpid也成功,获取了对应结果
}else{
//等待失败
}
进程不变,仅仅替换当前进程的 代码和数据
只要程序替换成功,就不会执行后续代码/ exec* 函数成功的时候不需要返回值检测,若exec*返回了就一定是调用失败了
让子进程执行一个“全新的程序”
execve:系统调用
int execl(const char *path, const char *arg, …);
int execlp(const char *file, const char *arg, …);
int execle(const char *path, const char *arg,…, char * const envp[]);
int execv(const char *path, char *const argv[]);
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[]);
参数:const char *path:要执行的目标程序的全路径(所在路径/文件名)
const char *arg, …:要执行的目标程序,可变参数列表,以NULL作为传参的结束
execl("/usr/bin/ls","ls","-a","-l","-i",NULL); char *argv[]={"ls","-a","-l","-i",NULL}; execv("/usr/bin/ls",argv); execlp("ls","ls","-a","-l","-i",NULL); execvp("ls",argv); execl("./myexe","myexe",NULL);// 程序调换 调用我的另一个程序 char *env[] = {"MYENV=myenv","MYENV2=myenv",NULL}; execle("./myexe","myexe",NULL,env); char *argv1[]={"myexe",NULL}; execve("./myexe",argv1,env);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。