当前位置: 首页 > news >正文

进程等待

一、进程等待必要性:

• 子进程退出,父进程如果不管不顾,就可能造成僵尸进程的问题,进而造成内存泄漏。

• 另外,进程一旦变成僵尸状态,那就刀枪不不入,kill-9也无能为力,因为谁也没有办法杀死⼀个已经死去的进程。

• 最后,父进程派给⼦进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是 不对,或者是否正常退出。

• 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char *argv[])
{pid_t id = fork();if (id == 0){int cnt = 5;while (cnt--){printf("我是一个子进程:%p,pid:%d,ppid%d\n", getpid(), getppid());sleep(1);}}// 父进程sleep(100);return 0;
}

以上代码最后会出现僵尸问题,接下来用进程等待的方式解决僵尸问题。

二、进程等待:

1.wait:status参数是个输出型参数,需要传整型变量的地址,把子进程这个退出信息给父进程拿到,wait接口等待任意一个退出的子进程,返回目标僵尸进程的退出码。

如果等待子进程没有退出,父进程会阻塞在wait处。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>int main(int argc, char *argv[])
{pid_t id = fork();if (id == 0){int cnt = 5;while (cnt--){printf("我是一个子进程:%p,pid:%d,ppid%d\n", getpid(), getppid());sleep(1);}}// 父进程sleep(100);pid_t rid = wait(NULL);if(rid>0){printf("wait success rid:%d", rid);}sleep(10);return 0;
}

2.waitpid:pid_ t waitpid(pid_t pid, int *status, int options);

简单等待就用wait,想要有更多状态信息就用waitpid。

返回值:当正常返回的时候 waitpid 返回收集到的子进程的进程 ID,如果设置了选项 WNOHANG, 而调用中 waitpid 发现没有已退出的子进程可收集 , 则返回 0,如果调用中出错 , 则返回-1, 这时 errno 会被设置成相应的值以指示错误所在。

pid : Pid=-1, 等待任⼀个子进程。与 wait 等效。 Pid>0. 等待其进程 ID 与 pid 相等的子进程。

options: 默认为0,表示阻塞等待。

WNOHANG: 若 pid 指定的子进程没有结束,则 waitpid() 函数返回 0 ,不予以等待。若正常结束,则返回该子进程的ID。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>int main(int argc, char *argv[])
{pid_t id = fork();if (id == 0){int cnt = 3;while (cnt--){printf("我是一个子进程:%p,pid:%d,ppid%d\n", getpid(), getppid());sleep(1);}exit(1);}// 父进程int status = 0;pid_t rid = waitpid(id, &status, 0);if (rid > 0){printf("wait success rid:%d , status:%d\n", rid, status);}else{printf("wait failed :%d:%s\n", errno, strerror(errno));}return 0;
}

status当作位图来看,被划分为若干区域,32比特位,从右向左,高16位不考虑,低16位里面的次低8位表示退出状态即退出码。后面有两部分,一部分叫core dump,占一个比特位默认为0,其他七个比特位表示退出时状态,没有异常,这8个数字都是0。所以整个数字就是1后面跟8个0就是2的8次方也就是256。

3.非阻塞等待:

父进程在等待子进程时周期性地去询问子进程的退出状态获取信息,直到等到子进程退出,利用非阻塞等待在子进程退出前可以让父进程去完成其他任务,解放生产力。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>// 函数指针类型
typedef void (*func_t)(); // 函数指针
#define NUM 5
func_t handlers[NUM + 1]; // 数组里面要有方法// 如下是任务
void DownLoad()
{printf("我是一个下载任务...\n");
}
void Flush()
{printf("我是一个刷新任务...\n");
}
void Log()
{printf("我是一个记录日志任务...\n");
}void registerHadnlers(func_t h[], func_t f)
{int i = 0;for (; i < NUM; i++){if (h[i] == NULL)break;}if (i == NULL)return;h[i] = f;h[i + 1] = NULL;
}int main(int argc, char *argv[])
{registerHadnlers(handlers, DownLoad);registerHadnlers(handlers, Flush);registerHadnlers(handlers, Log);pid_t id = fork();if (id == 0){int cnt = 3;while (cnt--){printf("我是一个子进程:%p,pid:%d,ppid%d\n", getpid(), getppid());sleep(1);}exit(10);}// 父进程int status = 0;pid_t rid = waitpid(id, &status, WNOHANG);if (rid > 0){printf("wait success rid:%d , exit code: %d , exit signal: %d\n", rid, (status >> 8) & 0xFF, status & 0x7F);}else if (rid == 0){for (int i = 0; handlers[i]; i++){handlers[i](); // 函数回调处理}printf("本轮调用结束 子进程没有退出\n");sleep(1);}else{printf("等待失败\n");}return 0;
}
http://www.dtcms.com/a/618522.html

相关文章:

  • 【数学速通】初中高中数学完整内容体系总结
  • 哪个网站做推销产品oshin wordpress
  • 网站qq获取大连在哪个省
  • 高职图书馆网站建设大赛wordpress 图片 存储
  • jEasyUI 设置排序指南
  • IconCache文件
  • Linux进程读写管道的行为详解
  • 零基础学做网站视频上传网站如何做
  • 仿RabbitMQ实现消息队列(三)--muduo介绍与使用
  • 4-Linux驱动开发-字符设备驱动
  • 专业网站建设平台郑州房产网
  • 43 全选,单选
  • stm32f103c8t6寄存器点灯法
  • 【Linux】计算机如何管理软硬件
  • 利用DuckDB列表一句SQL输出乘法口诀表
  • 兴宁网站设计凡客的官网
  • 大模型-Vllm 启用多模态数据-3
  • 集团网站建设定制网站建设中企动力是怎么建设网站的
  • Shell脚本猜数字,使用判断提示用户比目标数字是大还是小
  • 【开题答辩全过程】以 基于安卓的校园二手物品为例,包含答辩的问题和答案
  • 内测检测vs第三方软件检测的差异解析
  • 【科研绘图系列】R语言绘制多组条形图图(barplot)
  • Linux-线程
  • 最专业网站建设公备案域名是什么意思
  • SQL 约束
  • 创立一个网站要多少钱上海公司做网站的
  • MoE算法深度解析:从理论架构到行业实践
  • 【2025CVPR 异常检测方向】DFM: Differentiable Feature Matching for Anomaly Detection
  • 北京西站地铁是几号线做网站贵
  • 数据库第六次作业