3.exec函数族
1)exec函数族
- 让父子进程执行不相干的操作
- 能够替换进程地址空间中的源代码.txt段
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <iostream>
using namespace std;
int counter = 200;
int main() {
for (int i = 0; i < 8; ++i) {
cout << "parent i= " << i << endl;
}
pid_t pid = fork();
if (pid == 0) {
execl("/bin/ls", "ls", "-l",NULL);
}
for (int i = 0; i < 3; ++i) {
cout << "+++++++ i= " << i << endl;
}
return 0;
}
输出:
parent i= 0
parent i= 1
parent i= 2
parent i= 3
parent i= 4
parent i= 5
parent i= 6
parent i= 7
+++++++ i= 0
+++++++ i= 1
+++++++ i= 2
total 56
-rwxr-xr-x 1 root root 27456 Aug 13 09:34 ConsoleApplication1
-rwxr-xr-x 1 root root 12448 Aug 9 16:11 ConsoleApplication1.out
-rwxr-xr-x 1 root root 100 Aug 10 09:44 hello
---------- 1 root root 193 Aug 10 10:36 notecp.txt
-rw-r--r-- 1 root root 193 Aug 10 10:18 note.txt
- 当前程序中调用另外一个应用程序
- 首先想到exec之前需要fork
2)执行指定目录下的程序
- int execl(const char *path, const char *arg, ...);
- path:要执行的程序的绝对路径
- 变参arg:要执行的程序的需要的参数
- 第一arg:占位
- 后面的arg:命令的参数
- 参数写完后:NULL
- 一般执行自己写的程序
- int execl(const char *path, const char *arg[]);
- 参数:
- path = /bin/ps
- char* args[]={"ps","aux",NULL};
- execv("/bin/ps",args);
3)执行PATH环境变量能够搜索到的程序
- int execlp(const char *file,const char *arg,...);
- file:执行的命令的名字
- 第一arg:占位
- 后面的arg:命令的参数
- 参数写完之后:NULL
- 执行系统自带的程序
- execlp执行自定义的程序:file参数绝对路径
- int execvp(const char *path, const char *arg[]);
- 参数:
4.进程回收
1)孤儿进程
- 爹生孩子
- 爹先死,孩子还活着,孩子叫孤儿进程
- 孤儿被init进程领养
- 为了释放子进程占用的系统资源
- 进程结束后,能够释放用户区空间
- 释放不了pcb,必须由父进程释放
2)僵尸进程
- 孩子死了,父还活着,父进程不去释放子进程的pcb,子进程就变成了僵尸进程。
- 是一个已经死掉的进程。
3)进程回收
- wait-阻塞函数
- pid_t wait(int* status);
- 返回值:
- -1:回收失败,已经没有子进程了
- >0:回收的子进程对应的pid
- 参数:status
- 判断子进程是如何死的
- 正常退出:
- WIFEXITED(status):为非0 -》进程正常结束
- WEXITSTATUS(status):如果上宏为真,使用此宏-》获取进程退出状态(exit/return)的参数
- WIFEXITED(status):为非0 -》进程正常结束
- 被某个信号杀死了
- WIFSIGNALED(status):为非0 -》 进程异常终止
- WTERMSIG(status):如果上宏为真,使用此宏-》获取使得进程终止的那个信号的编号。
- WIFSIGNALED(status):为非0 -》 进程异常终止
- 正常退出:
- 判断子进程是如何死的
- 调用一次只能回收一个子进程
- 返回值:
- pid_t wait(int* status);
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<fcntl.h>
#include <iostream>
using namespace std;
int counter = 200;
int main() {
pid_t pid = fork();
if (pid > 0) {
cout << "parent process,pid = " << getpid() << " ppid = " << getppid() << endl;
int status;
pid_t wpid=wait(&status);
if (WIFEXITED(status)) {
cout << "exit value:" << WIFEXITED(status) << endl;
}
if (WIFSIGNALED(status)) {
cout << "exit by signal:" << WTERMSIG(status) << endl;
}
cout << "died child pid = " << wpid << endl;
}
else if (pid == 0) {
while (1) {
sleep(1);
cout << "child process,pid = " << getpid() << " ppid = " << getppid() << endl;
}
}
for (int i = 0; i < 5; ++i) {
cout << "i=" << i << endl;
}
return 9;
}
- waitpid
- pid_t waitpid(pid_t pid,int* status,int options);
- 函数作用:同wait函数
- 参数:
- pid:
- pid == -1 等待任一子进程。与wait等效。
- pid > 0 等待其进程id与pid相等的子进程。
- id == 0 等待其组id等于调用进程组id的任一子进程。
- pid < -1等待其组id等于pid的绝对值的任一子进程。
- status:子进程的退出状态,用法同wait函数
- options:设置为WNOHANG,函数非阻塞,设置为0,函数阻塞
- pid:
- 返回值:
- >0:返回清理掉的子进程ID;
- -1:无子进程
- =0:惨3为WNOHANG,且子进程正在运行。