父子进程
1. 退出关系
- 子进程继承了父进程的内容
父子进程有独立的地址空间, 互不影响
若父进程先结束
子进程成为孤儿进程,被init进程收养 ——》 子进程变成后台进程 若子进程先结束 ——》 父进程如果没有及时回收,子进程变成僵尸进程
2. 执行位置
fork 创建了子进程后,子进程从何处执行?
子进程从fork的下一条语句开始执行 父子进程谁先执行? 不确定,看操作系统先调度谁3. 进程回收函数 —— wait
#includepid_t wait(int * status);
成功时返回回收的子进程的进程号;失败时返回EOF
若子进程没有结束,父进程一直阻塞 若有多个子进程,哪个子进程先结束就先回收 (有多少个子进程,就应该有多少个wait)status
指定保存子进程返回值和结束方式的地址status
为Null
, 直接释放子进程PCB,不接收返回值 int void main(int argc, const char * argv[]){ int status; pid_t pid; if((pid ==fork()) < 0){ perror("fork");exit(-1); }else if(0 == pid){ sleep(1);exit(2); }else{ wait(&status); printf("%x\n", status); }}
进程返回值和结束方式
子进程通过exit/_exit/return
返回某个值(0-255) 父进程调用wait(&status)回收WIFEXITED(status) //判断子进程是否正常结束WEXITSTATUS(status) 获取子进程返回值WIFSIGNALEN(status) 判断子进程是否被信号结束WTERMSIG(status) 获取结束子进程的信号类型 status[15: 0][6:0]为0 表示正常结束 大于0 表示结束子进程的信号类型 [15:8] 子进程返回值
进程回收函数 —— waitpid
#includepid_t waitpid(pid_t pid, int * status, int option);
成功时返回回收的子进程的pid或0;失败时返回EOF
pid 可用于指定回收哪个子进程或任意子进程 status 制定用于保存子进程返回值和结束方式的地址 option指定回收方式,0或WNOHANGeg: waitpid(pid, &status, 0);
以阻塞方式回收指定子进程
waitpid(pid, &status, WNOHANG);
以非阻塞方式回收指定子进程(子进程没有结束返回0)
waitpid(-1, &status, 0) 等价于waitwaitpid(-1,&status, WNOHANG);
**进程结束 exit / _exit**
#include#include void exit(int status); stdlib.hvoid _exit(int status);
结束当前的进程并将status 返回
exit结束时会刷新(流)缓冲区exec函数族
进程调用exec函数族执行某个程序,进程当前内容被指定的程序替换
实现让父子进程执行不同的程序- 父进程创建子进程
- 子进程调用exec函数族
- 父进程不受影响 应用举例: shell
#includeint execl(const char *path, const char * arg, ...);int execlp(const char *file, const char * arg, ...);
成功时执行指定的程序; 失败时返回EOF
path 执行的程序的名称, 包含路径 arg... 传递给执行程序的参数列表 file 执行的程序的名称,在PATH中查找eg: if(execl("/bin/ls", "ls","-a", "-l", "/etc", NULL )<0){ perror("execl");}if(execlp("ls", "ls","-a", "-l", "/etc", NULL )<0){ perror("execl");}
int execv(const char * path, char * const argv[] );int execvp(const char * file, char * const argv[] );//成功时执行指定的程序; 失败时返回EOFeg;char * arg[] = {"ls", "-a", "-l", "/etc",NULL};if(execv("bin/ls", arg) < 0){ perror(execv);}if(execv("ls", arg) < 0){ perror(execvp);}
system
#includeint system(const char * command);
调用此进程先创建子进程,执行完后返回当前进程
成功时返回command的返回值, 失败时返回EOF 当前进程等待command执行结束后才继续执行