关于服装的网站规划与设计,天眼查官网查询入口,营销型企业网站建设的内容,移动端网站开发注意些什么目录
一#xff1a;进程常见的退出方法
1. main 函数返回值
2.调用 exit
3.调用 _exit
二#xff1a;异常问题
三#xff1a;进程等待
1.概念
2.进程等待的必要性
3.进程等待的方法
1#xff1a;wait --- 系统调用
2#xff1a;waitpid 进程…目录
一进程常见的退出方法
1. main 函数返回值
2.调用 exit
3.调用 _exit
二异常问题
三进程等待
1.概念
2.进程等待的必要性
3.进程等待的方法
1wait --- 系统调用
2waitpid 进程退出场景
代码运行完毕结果正确代码运行完毕结果不正确代码异常终止 一进程常见的退出方法 正常终止通过 echo $? 查看进程退出码 1: 从 main 返回 2: 调用 exit 3: 调用_exit 异常退出 ctrl c , 信号终止 1. main 函数返回值 echo $?
保存的是最近一个子进程执行完毕时的退出码。 测试代码
#includestdio.h
int main()
{printf(hahahagehe\n);return 10;
} 编译并运行代码然后查看进程的退出码 上述现象表明main 函数的退出码是可以被父进程获取的用来判断子进程的运行结果。 在C语言中我们学习过错误码那么错误码和退出码有什么区别呢
错误码通常是衡量一个库函数/一个系统调用一个函数的调用情况当失败的时候用来衡量函数进程出错的出错原因。
退出码通常是一个进程退出的时候它的退出结果。 2.调用 exit 通过 man 2 exit 命令 exit 信息 通过下述示例对比进行分析 在其他函数中进行 return ,表示的是函数调用结束进程不结束。 通过 echo $? 查看上述进程的退出码 我们发现进程的退出码为 10即函数中 exit 的返回值。由此我们可以得出结论
在任意地点调用 exit 表示进程退出不进行后续执行。
3.调用 _exit 那么 exit 和 _exit 的区别在哪里
exit终止进程的时候会自动刷新缓冲区 _exit 终止进程的时候不会自动刷新缓冲区 二异常问题
进程出异常本质是进程收到了对应的信号自己终止了! ---
所以一个进程是否出异常我们只要看有没有收到信号即可。
通过判断进程的退出码。
进程退出的三种场景中有 代码运行完毕结果正确代码运行完毕结果不正确代码异常终止 3 种其中前两种中的结果是否正确是由我们判断的那么这个我们指的是谁
在多进程环境中我们创建子进程的目的是为了让子进程帮我们做事我们需要得知子进程把事情做的怎末样这里的我们指的就是父进程 --- main 函数的返回值叫做进程的退出码0表示成功非0表示失败。
三进程等待
1.概念
通过 wait / waitpid 的方式让父进程一般对子进程进行资源回收的等待过程。
2.进程等待的必要性
1:解决子进程僵尸问题带来的内存泄漏
2:父进程创建子进程是要子进程来帮忙完成任务子进程任务完成的怎末样父进程要知道通过进程等待的方式获取子进程退出的信息 --- 两个数字 --- 不是必须的但是系统需要提供这样的基础功能。
3.进程等待的方法
1wait --- 系统调用 wait --- 等待任意一个子进程 返回值 成功返回被等待进程pid失败返回-1。 参数输出型参数获取子进程退出状态,不关心则可以设置成为NULL。 测试下述示例
#includestdio.h
#includeunistd.h
#includesys/wait.h
#includesys/types.h
#includestdlib.h
int main()
{pid_t id fork();if(id 0){//子进程int ret 5;while(ret){printf(i am child\n);sleep(1);ret--;}exit(0);}else {sleep(10);//父进程pid_t rid wait(NULL);if(rid id){printf(wait success\n);}}return 0;
}监视命令行脚本
while :;do ps ajx|head -1 ps ajx | grep myprocess | grep -v grep;sleep 1;echo #############################################################;done测试现象为 QQ录屏20230110123134 wait 进程等待能回收子进程僵尸状态 Z --- X如果子进程根本就没有退出父进程就必须在 wait 上进行堵塞等待直到子进程僵尸 wait 自动回收返回。
一般而言父子进程谁先运行不知道但是最后一般都是父进程最后退出 2waitpid waitpid --- 获取退出信息 返回值 当正常返回的时候waitpid返回收集到的子进程的进程ID如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在 参数 pid Pid-1,等待任一个子进程。与wait等效。Pid0.等待其进程ID与pid相等的子进程。 status: WIFEXITED(status): 若为正常终止子进程返回的状态则为真。查看进程是否是正常退出WEXITSTATUS(status): 若WIFEXITED非零提取子进程退出码。查看进程的退出码 options: WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0不予以等待。若正常结束则返回该子进程的ID。 对 wait 示例中的代码稍作修改观察现象 获取子进程 status wait和waitpid都有一个status参数该参数是一个输出型参数由操作系统填充。如果传递NULL表示不关心子进程的退出状态信息。否则操作系统会根据该参数将子进程的退出信息反馈给父进程。status不能简单的当作整形来看待可以当作位图来看待具体细节如下图只研究status低16比特位 测试示例代码跑完结果不正确
#includestdio.h
#includeunistd.h
#includesys/wait.h
#includesys/types.h
#includestdlib.h
int main()
{pid_t id fork();if(id 0){//子进程int ret 3;while(ret){printf(i am child\n);sleep(1);ret--;}exit(8);}else {printf(wait before\n);int status 0;//父进程pid_t rid waitpid(id,status,0);printf(wait after\n);if(rid id){printf(wait success: pid: %d,rid: %d,exit sig: %d,exit code: %d\n,getpid(),rid,status0x7F,(status 8)0xFF);}sleep(5);}return 0;
}运行效果 示例代码跑完结果正确 if(id 0){//子进程int ret 3;while(ret){printf(i am child\n);sleep(1);ret--;}exit(0);}
运行效果 示例代码异常 if(id 0){//子进程int ret 3;int a 5;while(ret){printf(i am child\n);sleep(1);a / 0;ret--;}}
运行效果 上述示例出异常但退出码为0
说明一个进程异常了收到信号它的退出码就没有意义了。
那么如何判断适度收到了信号呢通过 kill -l 查看exit sig 0; 表示正常。 父进程如何得知子进程的退出信息
wait / waitpid 系统调用接口
子进程退出的时候要修改状态Z。并将子进程的退出信号和退出码写入 pcb 中task_struct --
exit_code,exit_signal --- int * stausp 指向 int status。 options: 0:阻塞等待 WNOHANG:等待的时候以非阻塞的方式等待 rid 0 ,等待成功 breakrid 0 ,等待是成功的但是对方还没有退出 -- 做自己的事情。--- 循环rid 0 ,等待失败 break 测试代码正常退出
#includestdio.h
#includeunistd.h
#includesys/wait.h
#includesys/types.h
#includestdlib.h
int main()
{pid_t id fork();if(id 0){//子进程int ret 3;while(ret){printf(i am child,pid: %d ,ppid: %d ,ret: %d\n,getpid(),getppid(),ret);sleep(1);ret--;}exit(0);}//父进程while(1){int status 0;pid_t rid waitpid(-1,status,WNOHANG);if(rid 0){printf(child quit success,exit code:%d ,exit sig:%d\n,(status8)0xFF,status0x7F);break;}else if(rid 0){printf(wait failed!!!\n);break;}else {printf(--------------------------------------------------\n);//等待成功但子进程没有退出printf(child is alive,wait again,father do other thing ....\n);//父进程做自己的事情printf(--------------------------------------------------\n);}sleep(1);}return 0;
}运行效果为 修改 waitpid 部分的内容
pid_t rid waitpid(100,status,WNOHANG);运行效果为