进程概念
通俗的来说:进程就是运行中的程序;
在Linux中进程就是pcb(process control block),实际为一个struct结构体task_struct,称为进程控制块;
操作系统角度管理进程:进程就是操作系统对进程描述;
进程控制块中保存着进程的相关信息:
- 标识符(PID):描述本进程的唯一标识符,区别其他进程
- 进程状态
- 优先级:相对其他进程的优先级
- 内存指针
- 上下文数据
- 程序计数器
- io状态信息
- 记账信息
进程的创建:
fork()函数
复制:复制pcb–代码共享,数据独有
返回值:父进程返回子进程的PID>0 子进程返回0
vfork()-父子进程共用同一块虚拟地址空间
子进程先运行,并且子进程退出后或子进程替换运行另一段程序后,父进程才开始运行
https://blog.csdn.net/qq_42185602/article/details/89254091
进程的终止:
终止场景:
正常终止,结果符合预期;
正常终止,结果不符合预期;
异常终止
终止方式:main中return(释放资源);
exit()库函数(收尾操作后释放资源);
_exit()系统接口(直接释放资源退出);
进程的等待:
等待子进程的退出(避免产生僵尸进程)
子进程的退出时间,父进程未知,因此只能创建子进程后一直等待子进程退出
等待方式:wait(); waitpid();区别
#include<sys/types.h>
#include<wait.h>
pid_t wait(int *status);
//阻塞等待
//返回值:成功 返回等待进程的pid 失败返回-1
pid_T waitpid(pid_t pid, int *status, int options)
//正常返回waitpid 返回收集的pid
//如果options设置WHOHANG,则调用的waitpid没有发现退出的子进程可以收集,返回0
//调用出错返回-1,
//参数
//pid :
//pid = -1 返回任意一个子进程
//pid >0 ,等待与pid相同的子进程退出
//status:
//WIFEXITED(status) 若为正常返回子进程的返回状态,为真(是否正常退出)
//WEXITSTATUS(status) 若WIFEXITED非零,提取子进程退出码(查看子进程退出码)
//options:
//WHOHANG 若pid指定的子进程未退出,则waitpid直接返回0不予等待,正常返回,返回子进程pid
阻塞:为了完成操作发起调用,但是当前如果不具备完成条件,则一直等待,直到完成操作。
非阻塞:为了完成操作发起调用,但是如果不具备完成条件,则立即报错返回。
若子进程已经退出,wait/waitpid立即返回释放资源,获取子进程退出信息
若在任意时刻调用wait/waitpid,子进程存在且正常运行, 可能导致进程阻塞
不存在子进程,立即出错返回。
如果 status传递NULL代表不关心子进程退出状态信息。
程序的替换:
替换进程所运行的进程
将代码段虚拟地址经过页表所映射的物理地址区域(代码在内存中的位置)替换成另一块内存中的代码位置。
新的程序中有自己运行的程序,意味着虚拟地址空间中不仅代码段的映射位置改变了,并且数据段也需要重新初始化,映射到新程序数据段的位置。
替换函数:
exec函数族:
execl execlp execle
execv execvp execve
#include <unistd.h>
extern char **environ;
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[]);