进程控制(二):进程等待

news2024/10/5 21:20:03

文章目录

  • 进程控制(二)
  • 进程等待
    • wait函数
    • waitpid函数
    • wait/waitpid获取子进程状态码的过程
    • 进程等待相关的宏
  • 总结


进程控制(二)

延续对于上文进程结束,我们继续对于进程控制进行学习,本文我们主要是对于进程等待进行学习,进程等待,我们在前文初步接触进程的时候,我们知道,进程等待是指我们在运行该进程的时候,在等待资源,当有了资源分配后,便可以运行该进程,在本文中,我们认识的进程等待是指,子进程退出时,先进入僵尸状态,然后父进程进行等待(wait/waitpid)来获取子进程退出信息,这个过程叫做进程等待。

进程等待

进程等待,是子进程退出信息被父进程接收时,父进程处于等待状态的一种描述。

进程等待是指通过系统调用wait/waitpid,来进行对子进程进行状态检测与回收的功能。

  • 子进程退出时,如果父进程没有接收信息,那么会导致僵尸进程的问题,造成内存泄漏,所以父进程必须通过进程等待来回收子进程退出信息。(必要
  • 通过回收子进程的退出信息,也可以知道子进程退出码,以及是否出现异常,status。(可选

所以,我们必须要实现进程等待,防止内存泄漏,对于得到的子进程退出信息,我们可以选择性的利用,可有可无,看自己需求。

wait函数

wait函数,可以实现进程等待,只有一个参数,status,输出型参数,可以获得子进程退出信息

在这里插入图片描述

wait函数在2号手册上,头文件也可以表明,wait函数以及waitpid函数是系统调用接口,通过该函数来访问操作系统,使得操作系统对于子进程进行回收处理。

在这里插入图片描述

core dump,以后会用到,现在不需要掌握,只需要知道,这是用来进行调试的。

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>

#define N 10

void RunChild()
{
   int cnt=5;
   while(cnt)
   {
      printf("Child pid: %d, parent pid: %d\n",getpid(),getppid());//获取pid和ppid
      sleep(1);
      cnt--;
   }
   //printf("Child pid: %d, parent pid: %d\n",getpid(),getppid());//获取pid和ppid
   //sleep(15);
}

int main()
{
    //实现创建子进程,并对于子进程进行等待
    for(int i=0;i<N;i++)
    {
      pid_t id=fork();//创建子进程
      if(id==0)
      {
        RunChild();
        exit(i);//退出码
      }
      //父进程执行下面信息
      printf("create Child proc : %d success\n",id);
    }
    sleep(10);
    return 0;
}

上述代码,我们并没有是wait,会造成内存泄漏,下面我们来通过父进程来接收子进程的退出信息。

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>

#define N 10

void RunChild()
{
   int cnt=5;
   while(cnt)
   {
      printf("Child pid: %d, parent pid: %d\n",getpid(),getppid());//获取pid和ppid
      sleep(1);
      cnt--;
   }
   //printf("Child pid: %d, parent pid: %d\n",getpid(),getppid());//获取pid和ppid
   //sleep(15);
}

int main()
{
    //实现创建子进程,并对于子进程进行等待
    for(int i=0;i<N;i++)
    {
      pid_t id=fork();//创建子进程
      if(id==0)
      {
        RunChild();
        exit(i);//退出码
      }
      //父进程执行下面信息
      //wait;进程等待
      
      printf("create Child proc : %d success\n",id);
   }
    //进程等待
    for(int i=0;i<N;i++)
    {
        //会实现进程的等待
        pid_t id=wait(NULL);//wait等待是随机的,等待还没有被接收信息的子进程,有几个子进程就需要等几次。
        //int status=0;
        //pid_t id=wait(&status);//传地址,操作系统来进行存储子进程退出信息
        if(id>0)
        {
          //printf("wait %d success\n ; exit sig: %d\n",id,WEXITSTATUS(status));
          printf("wait %d success\n",id);
        }
    }
    return 0;
}

waitpid函数

waitpid函数,其拥有三个参数,功能相较于wait更多,可以认为waitpid可以包含wait的功能,wait的功能比较单一,智能获取状态码status,而且是随机等待子进程。

#include <sys/types.h>
#include <sys/wait.h>
 
pid_t waitpid(pid_t pid, int* status, int options);

参数介绍

返回值pid_t:

  • 大于0,表示等待子进程成功,返回值是子进程的pid
  • 小于0,表示等待子进程失败
  • 等于0,表示等待条件还没有就绪,此时父进程可以做自己的事情

pid参数:

  • 大于0,表示等待指定的子进程
  • pid = -1 ,表示等待随机子进程

status参数:

  • NULL,表示不需要子进程的状态码
  • 反之,作为输出型参数,操作系统将子进程退出信息写入status中

options参数:

  • 0,表示阻塞等待
  • WNOHONG,表示非阻塞等待

在这里插入图片描述

wait/waitpid获取子进程状态码的过程

wait和waitpid都是系统调用,为什么要通过系统调用函数,而不是库函数来实现该功能,这是因为,由于进程具有独立性,相互不影响,所以一般的函数无法访问到另一进程的内容,而系统调用,可以在全局上(操作系统的角度)来找到子进程PCB,得到状态码

等待流程

  1. 子进程运行完毕后,进入僵尸状态(Z),将退出码信息存储到子进程PCB中(exit_code,exit_signal),释放代码,以及数据,保留task_struct结构体信息。
  2. 父进程通过wait/waitpid,通过系统调用,得到子进程PCB中的退出信息,将推出信息,以位图的方式,写入到int类型的status参数,从而父进程得到子进程的推出信息。

exit_code:表示退出码

exit_signal:表示结束信号,也就是判断是否异常,如果为0,表示正常,如果非零,那就是接收了终止信号 kill -num,其中num==exit_signal

实现方式:

exit_signal == status&0x7F == WIFEXITED(status)

exit_code == status>>8&0xFF == WEXITSTATUS(status)

进程等待相关的宏

WEXITSTATUS(status):表示输出退出码(exit_code)

WNOHONG:表示非阻塞等待,用于waitpid的option参数。

WIFEXITED(status):通过状态码,表示子进程是否正常结束(是否异常),如果正常,返回ture

总结

进程等待,是父进程必须要完成的事情,是为了防止内存泄漏,也是为了知道子进程完成任务情况(由状态码得出结论),主要是了解wait/waitpid函数,以及status参数的构成,为什么能表示进程的三种退出情况,以及waitpid函数的非阻塞等待宏WNOHONG,还有退出码WEXITSTATUS,还有判断子进程是否正常退出的宏命令WIFEXITED。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1168261.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧渔业养殖远程监控解决方案

智慧渔业养殖远程监控解决方案 项目背景 影响水产养殖环境的关键参数就是水温、光照、溶氧&#xff0c;氨氮&#xff0c;硫化物、亚硝酸盐等&#xff0c;但这些关键因素即看不见又摸不着很难准确把握。现有的水产管理是以养殖经验为指导&#xff0c;也就是一种普遍的养殖经验…

证明char是定长的?

证明char是定长的&#xff1f; 大部分博客都在讲解char和varchar区别的时候都谈到char为定长&#xff0c;varchar为变长。 但是怎么证明char为定长呢&#xff1f; 下面是我证明的过程。 创建CHAR列&#xff1a;首先&#xff0c;创建一个CHAR列&#xff0c;指定其长度。例如&…

解决ECharts柱形图自定义单个柱子颜色图例无法显示

legend里data和series里的name需要对应series里对象需要设置stack属性&#xff0c;属性值都一样即可显示单柱重点在于series里对象data属性设置&#xff0c;必须使用&#xff0c;否则影响柱体上数值显示tooltip的值需要自定义&#xff0c;否则会显示堆叠柱状图的tooltip格式&am…

动手学深度学习——稠密连接网络DenseNet(原理解释+代码详解)

稠密连接网络DenseNet 1. 从ResNet到DenseNet2. 稠密块体3. 过渡层4. DenseNet模型5. 训练模型 CIFAR 和 SVHN 数据集上的错误率 (%)。DenseNet 比 ResNet 使用更少的参数&#xff0c;同时实现了更低的错误率。在没有数据增强的情况下&#xff0c;DenseNet 的性能大幅提高。 …

MySQL数据库之表的增删查改

目录 表的操作1.创建表创建表案例 2.查看表结构3.修改表4.删除表 表的操作 1.创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;说明&#xff1a; field 表示列…

pinia简单使用

新命令-创建vue3项目 vue create 方式使用脚手架创建项目&#xff0c;vue cli处理&#xff0c; vue3后新的脚手架工具create-vue 使用npm init vuelatest 命令创建即可。 在pinia中&#xff0c;将使用的组合式函数识别为状态管理内容 自动将ref 识别为stste,computed 相当于 ge…

Anaconda安装与配置

1.打开Anaconda官网&#xff0c;选择对应版本,下载到对应目录即可 或者进入: Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.双击打开.exe文件&#xff0c;然后点击next ; 3.点击agree 4.点击just me,然后next; 5.在Choose Install L…

百科创建系列天花板!一文看懂百度百科如何创建,百度百科怎么编辑才能通过!(百科创建必看)

在互联网时代&#xff0c;拥有一个权威的个人或企业信息展示平台显得尤为重要。百度百科作为全球最大的中文百科全书&#xff0c;已经成为了许多人和企业展示自己的重要途径。那么&#xff0c;如何创建一个百度百科词条呢&#xff1f; 分媒互动将为大家详细介绍百度百科创建的…

Locust:可能是一款最被低估的压测工具

01、Locust介绍 开源性能测试工具https://www.locust.io/&#xff0c;基于Python的性能压测工具&#xff0c;使用Python代码来定义用户行为&#xff0c;模拟百万计的并发用户访问。每个测试用户的行为由您定义&#xff0c;并且通过Web UI实时监控聚集过程。 压力发生器作为性…

第三章 python数据类型

系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…

Git https方式拉的代码IDEA推送代码报错

报错信息 fatal: could not read Username for ‘https://codehub-cn-south-1.devcloud.huaweicloud.com’: No such file or directory 18:18:39.885: [recovery_pattern] git -c credential.helper -c core.quotepathfalse -c log.showSignaturefalse push --progress --porc…

python第一课 变量

1.离线的情况下首选txt文档 2.有道云笔记 3.思维导图 xmind mindmaster 4.博客 5.wps流程图 # 变量的命名规则 1.变量名只能由数字字母下划线组成 2.变量名不能以数字开头 3.变量名不能与关键字重名 快捷键 撤销&#xff1a;Ctrl/Command Z 新建&#xff1a;Ctrl/Com…

【CesiumJS】(1)Hello world

介绍 Cesium 起源于2011年&#xff0c;初衷是航空软件公司(Analytical Graphics, Inc.)的一个团队要制作世界上最准确、性能最高且具有时间动态性的虚拟地球。取名"Cesium"是因为元素铯Cesium让原子钟非常准确&#xff08;1967年&#xff0c;人们依据铯原子的振动而对…

气膜场馆的降噪方法

在现代社会&#xff0c;噪音已经成为我们生活中难以避免的问题&#xff0c;而气膜场馆也不例外。传统的气膜场馆常常因其特殊结构而面临噪音扩散和回声问题&#xff0c;影响了人们的体验和活动效果。然而&#xff0c;随着科技的进步&#xff0c;多功能声学综合馆应运而生&#…

413 (Payload Too Large) 2023最新版解决方法

文章目录 出现问题解决方法 出现问题 博主在用vue脚手架开发的时候&#xff0c;在上传文件的接口中碰到 这样一个错误&#xff0c;查遍所有csdn&#xff0c;都没有找到解决方法&#xff0c;通过一些方式&#xff0c;终于解决了。 解决方法 1.打开Vue项目的根目录。 2.在根目…

what?腾讯云3年轻量2核4G5M服务器566.6元哪去了?

what&#xff1f;腾讯云3年轻量2核4G5M服务器566.6元哪去了&#xff1f;腾讯云双11优惠活动3年轻量2核4G5M服务器从566.6元涨价到756元三年&#xff0c;3年轻量2核2G4M服务器从366.6元恢复到540元三年&#xff0c;大家抓紧吧&#xff0c;三年轻量已经库存已经不多了&#xff0c…

EthernetIP主站转EtherCAT协议网关采集电力变压器的 Ethernet IP 数据

怎么通过捷米JM-EIPM-ECT网关把ABB电力变压器的 Ethernet IP 数据&#xff0c;连接到欧姆龙PLC上&#xff0c;通过plc去监控电力设备的数据呢&#xff0c;下面是介绍简单的连接方法&#xff0c;采集Ethernet IP从站数据和EtherCAT协议 1 &#xff0c;捷米JM-EIPM-ECT网关连接Et…

基于51单片机电子秤-proteus仿真-源程序

一、系统方案 本设计采用52单片机作为主控器&#xff0c;液晶1602显示&#xff0c;HX711模块&#xff0c;按键设置单价&#xff0c;计算总价&#xff0c;超量程报警&#xff0c;蜂鸣器报警。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 I…

基于openresty waf二次开发多次匹配到的ip再做拉黑

我们想在openresty waf的基础上做二次开发&#xff0c;比如再精确一些。比如我们先匹配到了select的url我们先打分10分&#xff0c;匹配到cc 1000/s我们再给这个ip打10分…直到100分我们就拉黑这个ip。 [openresty waf][1] #cat reids_w.lua require lib local redis require…

Zookeeper安装及配置

Zookeeper官网:Apache ZooKeeper 一般作为服务注册中心 无论在Windows下还是Linux下,Zookeeper的安装步骤是一样的,用的包也是同一个包 Window下安装及配置Zookeeper 下载后解压 linux安装 window及Linux安装及配置zookeeper_访问windos上的zookeeper-CSDN博客