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

Linux中的进程等待

文章目录

  • 1.进程等待
    • 1.1进程等待必要性
      • 1.1.1为什么有进程等待这个概念
      • 1.1.2进程等待是什么?
      • 1.1.3进程等待具体干什么?
    • 1.2进程退出方法:
  • 2.具体代码实现

1.进程等待

1.1进程等待必要性

1.1.1为什么有进程等待这个概念

之前讲过,子进程退出,如果父进程不管不问,那么就可能会造成僵尸进程的问题,僵尸进程杀不死,本节所讲的进程等待就是杀掉僵尸进程的方法,从而解决因为僵尸进程而导致的内存泄漏问题。我们要通过进程等待,来获取子进程的退出情况,即:知道父进程我布置给子进程的任务完成的怎么样了,要么关心,也可能不关心(通过设置选项可以选择关心与否)。

1.1.2进程等待是什么?

通过系统调用wait/waitpid,来进行对进程运行状态进行检测与回收功能。

1.1.3进程等待具体干什么?

通过代码实现:父进程通过调用wait/waitpid进行僵尸进程的回收问题!

1.2进程退出方法:

wait方法:

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int*status);
返回值:
成功返回被等待进程pid,失败返回-1。
参数:
输出型参数,获取子进程退出状态,不关心则可以设置成为NULL

例如如下代码:

#include<stdio.h>2 #include<sys/types.h>3 #include<sys/wait.h>4 #include <stdlib.h>5 #include <unistd.h>6 int main()7 {8   pid_t id = fork();9   if(id == 0)10   {11     printf("I am a Child Process,pid:%d,ppid:%d\n",getpid(),getppid());12     exit(1);13   }              14   else if(id < 0)                                                                                                                            15   {                  16       perror("fork");17       return 1;18   }19   else20   {21 	while(1)22     {23       pid_t ret = wait(NULL);24       if(ret < 0)                                                                                                                            25       {26         printf("wait failed\n");27         break;28       }29       else if(ret >0)30       {31         printf("进程是正常跑完的, 退出码:%d\n",ret);32         break;33       }34       else{35         printf("进程还结束,请等待哦\n");36         break;37       }38     }39   }

运行结果为:
在这里插入图片描述
waitpid方法:
pid_ t waitpid(pid_t pid, int *status, int options);
返回值:
当正常返回的时候waitpid返回收集到的子进程的进程ID
如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0
如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
参数:

  1. pid:Pid=-1,等待任一个子进程。与wait等效。Pid>0.等待其进程ID与pid相等的子进程
  2. status:WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
    WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
  3. options:
    WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
1.如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,
并且释放资源,获得子进程退出信息。
2.如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。
3.如果不存在该子进程,则立即出错返回。

代码如下:

#include<stdio.h>2 #include <stdlib.h>3 #include <unistd.h>4 #include <sys/types.h>5 #include <sys/wait.h>6 7 #define N 108 void RunChild()9 {10     int cnt = 5;11     while(cnt)12     {13         printf("I am Child Process, pid: %d, ppid:%d\n", getpid(), getppid());14         sleep(1);15         cnt--;16     }17 }18 int main()19 {20	 /*for(int i=0;i<N;i++)21   {22     pid_t id = fork();23     if(id == 0)24     {                                                                                                                                        25       RunChild();26       exit(i);27     }28     printf("Creat Child Process: %d Success\n",id);29   }30   return 0;*/31   pid_t id = fork();32   if(id < 0)33   {34     perror("fork");35     return 1;36   }37   else if (id ==0)38   {39     int cnt =5;40     while(cnt)41     {42       printf("I am child,pid:%d,ppid:%d,cnt:%d\n",getpid(),getppid(),cnt);43       cnt--;44       sleep(1);45     }46 exit(11);47   }48   else{49    /* int cnt = 5;50      while(cnt)51      {52           printf("I am father, pid:%d, ppid:%d, cnt: %d\n", getpid(), getppid(), cnt);53           cnt--;54           sleep(1);55      }*/ 56     int status = 0;57     while(1)                                                                                                                                 58     {59       pid_t ret = waitpid(id, &status, WNOHANG); //非阻塞60       if(ret > 0)61       {62         if(WIFEXITED(status))63         {64           printf("进程是正常跑完的,退出码为:%d\n",WEXITSTATUS(status));65         }66         else 67         {68           printf("进程异常退出了。\n");69         }}                                                                                                                                    70         break;71       }72       else if(ret <0)73       {74         printf("wait failed\n");75         break;76       }77       else{78         printf("你好了没?子进程还没有退出,我在等等...\n");79         sleep(1);80       81       }82 83     }84   }85   return 0;86 }

在这里插入图片描述
在这里插入图片描述
获取子进程status:

  1. wait和waitpid,都有一个status参数,该参数是一个输出型参数由操作系统填充
  2. 如果传递NULL,表示不关心子进程的退出状态信息。否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
  3. status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特位):
    在这里插入图片描述
    测试代码如下:
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main( void )
{pid_t pid;if ( (pid=fork()) == -1 )perror("fork"),exit(1);if ( pid == 0 ){sleep(20);exit(10);} 	else {int st;int ret = wait(&st);if ( ret > 0 && ( st & 0X7F ) == 0 ){ // 正常退出printf("child exit code:%d\n", (st>>8)&0XFF);} else if( ret > 0 ) { // 异常退出printf("sig code : %d\n", st&0X7F );}}
}

测试结果为:
在这里插入图片描述

2.具体代码实现

进程的阻塞等待方式:

int main()
{pid_t pid;pid = fork();if(pid < 0){printf("%s fork error\n",__FUNCTION__);//__FUNCTION__: ,这是一个预编译器内置宏,它会被替换为当前函数的名称。//所以,如果你在函数my_function中调用了这条语句,__FUNCTION__会被替换为"my_function"。如果fork函数出错(通常fork的返回值是-1表示出错),则打印出“函数名 fork error”并换行。return 1;} else if( pid == 0 ){ //childprintf("child is run, pid is : %d\n",getpid());sleep(5);exit(257);} else{int status = 0;pid_t ret = waitpid(-1, &status, 0);//阻塞式等待,等待5Sprintf("this is test for wait\n");if( WIFEXITED(status) && ret == pid ){printf("wait child 5s success, child return code is:%d.\n",WEXITSTATUS(status));}else{printf("wait child failed, return.\n");return 1;}}return 0;
}

进程的非阻塞等待方式:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{pid_t pid;pid = fork();if(pid < 0){printf("%s fork error\n",__FUNCTION__);return 1;}else if( pid == 0 ){ //childprintf("child is run, pid is : %d\n",getpid());sleep(5);exit(1);} else{int status = 0;pid_t ret = 0;do{ret = waitpid(-1, &status, WNOHANG);//非阻塞式等待if( ret == 0 ){printf("child is running\n");}sleep(1);}while(ret == 0);if( WIFEXITED(status) && ret == pid ){printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));}else{printf("wait child failed, return.\n");return 1;}}return 0;
}

相关文章:

Linux中的进程等待

文章目录 1.进程等待1.1进程等待必要性1.1.1为什么有进程等待这个概念1.1.2进程等待是什么&#xff1f;1.1.3进程等待具体干什么&#xff1f; 1.2进程退出方法&#xff1a; 2.具体代码实现 1.进程等待 1.1进程等待必要性 1.1.1为什么有进程等待这个概念 之前讲过&#xff0c…...

ubuntu22.04桌面完整版配置WiFi方法(修改磁盘文件方式--不需要显示器)(注意了:后来发现这个方法是错误的!!!)

打开这个文件&#xff1a; /etc/network/interfaces 一般来说这个文件是无法修改的&#xff0c;但是可以通过在/etc/network/文件夹找一个叫做interfaces.d的文件夹&#xff0c;(正常的Ubuntu系统跟这个树莓派的Ubuntu系统不一样&#xff0c;正常系统没有这个interfaces文件)…...

React项目使用craco修改webpack配置

React项目使用craco 通过Create React App&#xff08;CRA&#xff09;搭建的react项目&#xff0c;webpack的相关配置是被默认隐藏起来的&#xff0c;如果想修改关于webpack的相关配置&#xff0c;有两种方式&#xff1a; npm run ejectcraco npm run eject npm run eject…...

@RunWith(SpringRunner.class)注解的作用

通俗点&#xff1a; RunWith(SpringRunner.class)的作用表明Test测试类要使用注入的类&#xff0c;比如Autowired注入的类&#xff0c;有了RunWith(SpringRunner.class)这些类才能实例化到spring容器中&#xff0c;自动注入才能生效 官方点&#xff1a; RunWith 注解是JUnit测…...

深入理解网络IO复用并发模型

本文主要介绍服务端对于网络并发模型以及Linux系统下常见的网络IO复用并发模型。文章内容一共分为两个部分。 第一部分主要介绍网络并发中的一些基本概念以及我们Linux下常见的原生IO复用系统调用&#xff08;epoll/select&#xff09;等。第二部分主要介绍并发场景下常见的网…...

二叉树采用二叉链表存储:编写计算整个二叉树高度的算法

二叉树采用二叉链表存储&#xff1a;编写计算整个二叉树高度的算法 (二叉树的高度也叫二叉树的深度) 代码思路&#xff1a; 首先你要明白什么是树的高度&#xff0c;简言之就是树有多少层&#xff0c;如下图&#xff1a; 下面这棵树的高度就是4 首先我们观察根节点&#xff0…...

antd Cascader级联菜单无法赋值回显问题

说起来太丢人了&#xff0c;自己还拿官网例子在这里调试半天&#xff0c;最后发现是一个特别小儿科的问题哈哈 Cascader级联数据是服务端返回然后自己处理过的&#xff0c;使用了cascader的fileNames属性重置字段名&#xff0c;最后发现服务端回传的数据无法赋值回显在组件上&…...

在react中使用redux react-redux的使用demo

前言: redux是一种状态管理工具,可以存储和操作一些全局或者很多组件需要使用的公共数据。 平心而论,redux的使用对于新上手来说不太友好,多个依赖包的,多种api的结合使用,相对来说比做同样一件事的vuex用起来比较麻烦.不过,熟能生巧,用多了也就习惯了,下面是个人的一个demo,…...

Flutter 06 动画

一、动画基本原理以及Flutter动画简介 1、动画原理&#xff1a; 在任何系统的Ul框架中&#xff0c;动画实现的原理都是相同的&#xff0c;即&#xff1a;在一段时间内&#xff0c;快速地多次改变Ul外观&#xff1b;由于人眼会产生视觉暂留&#xff0c;所以最终看到的就是一个…...

优化改进YOLOv5算法之添加MS-Block模块,有效提升目标检测效果(超详细)

目录 前言 1 MS-Block原理 1.1 Multi-Scale Building Block Design 1.2 Heterogeneous Kernel Selection Protocol 2 YOLOv5算法中加入MS-Block...

【论文阅读】Iterative Poisson Surface Reconstruction (iPSR) for Unoriented Points

文章目录 声明作者列表核心思想归纳算法流程机器翻译声明 本帖更新中如有问题,望批评指正!如果有人觉得帖子质量差,希望在评论中给出建议,谢谢!作者列表 FEI HOU(侯飞)、CHIYU WANG、WENCHENG WANG:中国科学院大学 HONG QIN CHEN QIAN、YING HE 核心思想归纳 当一条从…...

通过akshare获取股票分钟数据

参考:https://blog.csdn.net/qnloft/article/details/131218295 import akshare as ak 个股的 df ak.stock_zh_a_hist_min_em(symbol“000001”, start_date“2023-11-03 09:30:00”, end_date“2023-11-03 15:00:00”, period‘1’, adjust‘’) print(df) date_info df[‘…...

【论文阅读笔记】Traj-MAE: Masked Autoencoders for Trajectory Prediction

Abstract 通过预测可能的危险&#xff0c;轨迹预测一直是构建可靠的自动驾驶系统的关键任务。一个关键问题是在不发生碰撞的情况下生成一致的轨迹预测。为了克服这一挑战&#xff0c;我们提出了一种有效的用于轨迹预测的掩蔽自编码器(Traj-MAE)&#xff0c;它能更好地代表驾驶…...

MySQL - Zero date value prohibited

问题: timestamp字段报Caused by: com.mysql.cj.exceptions.DataReadException: Zero date value prohibited 原因: timestamp字段存入了0值, 超出了最小值1900-01-01 00:00:00, 转Java对象的时候报错 解决: 1.修复或删除原数据 2. mysqlurl 中添加zeroDateTimeBehaviorconve…...

设计模式——迭代器模式(Iterator Pattern)+ Spring相关源码

文章目录 一、迭代器模式二、例子2.1 菜鸟例子2.1.1 定义迭代器接口2.1.2 定义迭代对象接口——用于返回一个迭代器2.1.3 实现 迭代对象 和 迭代器2.1.4 使用 2.2 JDK源码——ArrayList2.3 Spring源码——DefaultListableBeanFactory 三、其他设计模式 一、迭代器模式 类型&am…...

【word技巧】ABCD选项如何对齐?

使用word文件制作试卷&#xff0c;如何将ABCD选项全部设置对齐&#xff1f;除了一直按空格或者Tab键以外&#xff0c;还有其他方法吗&#xff1f;今天分享如何将ABCD选项对齐。 首先&#xff0c;我们打开【替换和查找】&#xff0c;在查找内容输入空格&#xff0c;然后点击全部…...

如何在uni-app小程序端实现长按复制功能

在开发小程序应用中&#xff0c;常常需要使用到长按复制功能。本文将介绍如何在uni-app小程序端实现长按复制功能。 uni-app是一个跨平台的开发框架&#xff0c;可以基于vue.js语法开发小程序、H5、APP等多个平台的应用。uni-app提供了一些内置组件和API&#xff0c;可以方便地…...

基于springboot实现在线考试平台项目【项目源码+论文说明】计算机毕业设计

基于springboot实现在线考试演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把在线考试管理与现在网络相结合&#xff0c;利用java技术建设在线考试系统&#xff0c;实现在线考试的信息化。则对于进一步提高在线考试管理发展&#xff0c;丰富在线考试管理经验能起到不少…...

【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取(北斗、GPS和GNSS)

【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取&#xff08;北斗、GPS和GNSS&#xff09; 测试视频&#xff08;其中的恶性BUG会在下一篇文章阐述&#xff09;&#xff1a; 【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG&#xff08;目前没有完全的…...

软件设计师2016下半年下午——KMP算法和装饰设计模式

下面是提供的代码的逐行注释&#xff0c;以及对next数组在KMP算法中的作用的解释&#xff1a; #include <iostream> #include <vector> using namespace std;void buildNextArray(const char* pattern, vector<int>& next) {int m strlen(pattern); …...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...