Linux之进程--进程控制 在操作系统中进程控制Process Control是最核心、最基础的系统能力之一。我们运行的每一个程序、每一条命令本质都是操作系统对进程的创建、调度、等待和销毁的完整生命周期管理。一、进程控制核心概念进程是操作系统资源分配和调度的基本单位每个进程都有唯一的PID进程ID并由 PCB进程控制块维护状态、资源、父子关系等信息。Linux 下所有进程均由父进程创建子进程最终形成以init/systemd为根的进程树。进程的完整生命周期分为三步创建父进程通过系统调用生成子进程运行/终止子进程执行业务逻辑主动或被动退出等待回收父进程获取子进程退出状态回收资源避免僵尸进程二、进程创建进程创建在之前的学习我们就了解过一部分fork一个新的进程就是内核数据结构代码,数据二、进程创建进程创建在之前的学习我们就了解过一部分fork创建子进程一个新的进程就是内核数据结构代码,数据fork 返回值三种情况pid0当前是父进程返回值为子进程 pidpid0当前是子进程pid0fork 失败进程数达到系统上限、内存不足为什么我们要创建进程??让子进程和父进程分流,子进程跑父进程的代码1父子进程分流执行分担任务fork之后父子进程共享同一份程序代码但拥有独立进程调度流fork返回值区分逻辑父进程返回子进程 pid子进程返回 0父进程负责监听、调度、等待子进程单独执行业务逻辑两者互不阻塞。 典型场景网络服务器每来一条客户端连接就 fork 一个子进程处理读写。完成进程替换2配合 exec 系列函数完成进程程序替换单纯 fork 只能复制父进程代码如果想让子进程运行全新可执行程序比如 shell 执行外部命令必须搭配exec族函数fork创建子进程复刻父进程环境子进程内部调用execvp/execve丢弃原有代码段加载新程序 父进程不受影响继续原有逻辑。 场景bash 输入lsshell 先 fork 子进程子进程 exec 替换为 ls 程序执行。写时拷贝vs浅拷贝浅拷贝写时拷贝操作系统会将进程fork出来之后的进程他们的数据变成只读如果有任意一方要对数据来进行修改,那么os不会让其直接对该数据进行修改,会先将数据拷贝出来一份,然他再备份的那一块再进行改三、进程终止进程终止就是要释放代码和数据内核数据结构首先先释放代码和数据,然后再释放内核数据结构为什么呢??因为父进程是要知道子进程结束的的具体信息,可以分为以下三种a,b,c都可以利用两个变量来记录这个信息int sigint exit_code再main函数中return的就是进程退出码查看进程终止信号echo ?进程退出码可以根据我们自己自定义也可以是用系统的strerror1.查看系统自己的strerror系统的退出码对应的信息但是我们使用的比较多的还是自定义依靠我们自定义的宏对于C这种情况我们需要知道什么情况使其发生异常,怎么被kill所以退出码对其并没有意义选项场景描述是否触发信号对应信号名称 信号编号 (Signumber)a代码结束返回正确无信号无b代码结束结果不符合预期无信号无c代码未跑完进程异常结束有致命信号1.SIGINT(2)CtrlC 中断2.SIGSEGV(11)段错误3.SIGKILL(9)强制杀进程4.SIGFPE(8)除零崩溃那么应该要怎么退出呢exit vs _exit这是我们之前学到的僵尸进程子进程结束后,父进程没有对子进程进行回收,子进程会一直处于僵尸状态,当我再命令界面ctrlc会将全部的进程都杀死四、进程等待Waitpid_t wait(int *wstatus);wstatus传出参数保存子进程退出状态传NULL表示不关心退出码。阻塞等待:没有子进程退出,父进程一直等待.直到任意一个子进程结束,而且只能是任意的子进程不能说自己想要的子进程执行pid_t ret fork();后系统会生成两份独立进程同一个 fork 返回两个不同值父进程返回 新创建子进程的 PID正整数子进程返回0创建失败内存不够、进程数上限父子都返回-1ret接收了wait子进程的pidWaitpid#include sys/wait.h pid_t waitpid(pid_t pid, int *wstatus, int options);参数 1pid —— 指定要等待的子进程核心区分点分 4 种取值规则pid 0只等待 PID pid 这唯一一个子进程其他子进程退出也不会触发返回。 例waitpid(child_pid, st, 0)只等刚才 fork 出的子进程。pid 0等待和当前父进程同进程组的任意子进程。pid -1等待所有子进程等价wait(st)。pid -1取绝对值abs(pid)作为进程组 ID等待该进程组下所有子进程。参数 2wstatus —— 接收子进程退出状态传NULL不关心子进程退出码丢弃状态传int变量地址内核会把子进程退出信息存入该变量配合宏解析看是否正常终止,如果正常终止就就返回0非正常终止要看退出码参数 3options —— 控制阻塞行为位或组合0默认阻塞模式无特殊功能。WNOHANG非阻塞 没有子进程退出时函数立刻返回0父进程不会卡住可以继续执行业务逻辑。WUNTRACED子进程收到SIGSTOP/SIGTSTP暂停时waitpid 也会返回。WCONTINUED暂停的子进程收到SIGCONT恢复运行时waitpid 也会返回。看一下下面那个现象status对应的不是退出码吗???为什么这里显示不是1,而是256当然我们也可以尝试用真的退出码故意让被除数为0;第 8 个信号8) SIGFPE 含义浮点运算异常除零、浮点数溢出等。父进程通过waitpid是如何获得子进程的退出信息的??子进程结束后不会立即退出,先是释放代码和数据,但是内核数据结构并没有释放,里面记录退出码和退出信号并且处于Z状态,父进程可以通过waitpid获取子进程的pid和一些信息