无涯教程-进程 - 子进程监控

news2024/11/20 21:20:07

正如我们所看到的,每当我们使用fork从程序创建子进程时,都会发生以下情况-

  • 当前进程成为父进程
  • 新进程成为子进程

如果父进程比子进程提前完成任务然后退出,会发生什么?现在谁将成为子进程的父进程?子进程的父进程是init进程,它是启动所有任务的第一个进程。

为了监视子进程的执行状态,检查子进程是正在运行还是已停止或检查执行状态等,使用wait()系统调用。

让我们考虑一个示例程序,其中父进程不等待子进程,这导致init进程成为子进程的新父进程。

文件名:parentprocess_nowait.c

#include<stdio.h>

int main() {
   int pid;
   pid = fork();
   
   //Child process
   if (pid == 0) {
      system("ps -ef");
      sleep(10);
      system("ps -ef");
   } else {
      sleep(3);
   }
   return 0;
}

编译和执行步骤

UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 Jan20 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql       101      1  0 Jan20 ?        00:04:41 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mariadb/mariadb.log --pid-file=/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock
3108506    5445      0  0 Jan22 ?        00:01:19 [/sbin/klogd -c ] <defunct>
4688328    5446      0  0 Jan22 ?        00:01:19 [/sbin/klogd -c ] <defunct>
4688328   21894      0  0 Jan22 ?        00:01:19 [/sbin/klogd -c ] <defunct>
3108506   21895      0  0 Jan22 ?        00:01:19 [/sbin/klogd -c ] <defunct>
4688328   27309      0  0 Jan22 ?        00:00:00 [/sbin/klogd -c ] <defunct>
3108506   27311      0  0 Jan22 ?        00:00:00 [/sbin/klogd -c ] <defunct>
8295652   32407      0  0 Jan20 ?        00:00:39 /sbin/klogd -c 1 -x -x
4688328   49830      0  0 Jan20 ?        00:00:18 /sbin/klogd -c 1 -x -x
3108506   50854      0  0 Jan20 ?        00:00:18 /sbin/klogd -c 1 -x -x
4688328   64936      0  0 Jan22 ?        00:00:59 [/sbin/klogd -c ] <defunct>
3108506   64937      0  0 Jan22 ?        00:00:59 [/sbin/klogd -c ] <defunct>
4688328   67563      0  0 Jan22 ?        00:00:59 [/sbin/klogd -c ] <defunct>
7528790   80536      0  0 Jan20 ?        00:01:09 [/sbin/klogd -c ] <defunct>
6327201   80542      0  0 Jan20 ?        00:01:09 [/sbin/klogd -c ] <defunct>
4688328   82050      0  0 Jan22 ?        00:01:59 [/sbin/klogd -c ] <defunct>
3108506   82051      0  0 Jan22 ?        00:01:59 [/sbin/klogd -c ] <defunct>
7528790   84116      0  0 Jan20 ?        00:00:27 /sbin/klogd -c 1 -x -x
7528790   84136      0 19 Jan20 ?        21:13:48 /sbin/klogd -c 1 -x -x
7528790   84140      0  0 Jan20 ?        00:00:28 /sbin/klogd -c 1 -x -x
7528790   87629      0  0 Jan20 ?        00:00:39 /sbin/klogd -c 1 -x -x
7528790   87719      0  0 Jan20 ?        00:00:27 /sbin/klogd -c 1 -x -x
8023807  164138      0  0 05:41 ?        00:00:00 main
8023807  164897 164138  0 05:41 ?        00:00:00 ps -ef

以下是监视子进程的系统调用的变体-

  • wait()
  • waitpid()
  • waitid()

wait() 函数调用将等待子进程之一终止,并在缓冲区中返回其终止状态,如下所述。

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);

此调用成功返回终止子进程的进程ID,失败返回-1。 wait()调用暂停当前进程的执行,并无限期等待,直到其子进程之一终止。

让我们修改前面的程序,以便父进程现在等待子进程。

文件名:parentprocess_waits.c

#include<stdio.h>

int main() {
   int pid;
   int status;
   pid = fork();
   
   //Child process
   if (pid == 0) {
      system("ps -ef");
      sleep(10);
      system("ps -ef");
      return 3; //exit status is 3 from child process
   } else {
      sleep(3);
      wait(&status);
      printf("In parent process: exit status from child is decimal %d, hexa %0x\n", status, status);
   }
   return 0;
}

编译和执行步骤

UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 Jan20 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql       101      1  0 Jan20 ?        00:04:42 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mariadb/mariadb.log --pid-file=/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock
3108506    5445      0  0 Jan22 ?        00:01:19 [/sbin/klogd -c ] <defunct>
8023807  191762      0  0 05:47 ?        00:00:00 sh -c cd /home/cg/root/8023807; timeout 10s main
8023807  191768 191762  0 05:47 ?        00:00:00 timeout 10s main
8023807  191769 191768  0 05:47 ?        00:00:00 main
8023807  191770 191769  0 05:47 ?        00:00:00 main
8023807  192193      0  0 05:47 ?        00:00:00 sh -c cd /home/cg/root/8023807; timeout 10s main
8023807  192199 192193  0 05:47 ?        00:00:00 timeout 10s main
8023807  192200 192199  0 05:47 ?        00:00:00 main
8023807  192201 192200  0 05:47 ?        00:00:00 main
8023807  192202 192201  0 05:47 ?        00:00:00 ps -ef

wait()  系统调用具有局限性,例如它只能等到下一个子进程的退出。如果我们需要等待特定的子进程,则不能使用wait(),可以使用waitpid()系统调用。

waitpid()  系统调用将等待指定的子进程终止,并在缓冲区中返回其终止状态,如下所述。

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

上面的调用在成功时返回终止子进程的进程ID,在失败时返回-1。 waitpid()系统调用暂停当前进程的执行,并无限期等待,直到指定的子进程终止为止。

默认情况下,waitpid()系统调用仅等待终止的子进程,但是可以使用选项参数修改此默认行为。

现在,让我们以一个程序为例,等待带有其进程ID的特定进程。

/*文件名:waitpid_test.c * /

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

int main() {
   int pid;
   int pids[3];
   int status;
   int numprocesses = 0;
   int total_processes = 3;
   while (numprocesses < total_processes) {
      pid = fork();
      
      //Child process
      if (pid == 0) {
         printf("In child process: process id is %d\n", getpid());
         sleep(5);
         return 4;
      } else {
         pids[numprocesses] = pid;
         numprocesses++;
         printf("In parent process: created process number: %d\n", pid);
      }
   }
   
   //Waiting for 3rd child process
   waitpid(pids[total_processes - 1], &status, 0);
   if (WIFEXITED(status) != 0) {
      printf("process %d exited normally\n", pids[total_processes - 1]);
      printf("exit status from child is %d\n", WEXITSTATUS(status));
   } else {
      printf("process %d not exited normally\n", pids[total_processes - 1]);
   }
   return 0;
}

编译并执行后,输出如下。

In child process: process id is 32528
In parent process: created process number: 32528
In child process: process id is 32529
In parent process: created process number: 32528
In parent process: created process number: 32529
In child process: process id is 32530
In parent process: created process number: 32528
In parent process: created process number: 32529
In parent process: created process number: 32530
process 32530 exited normally
exit status from child is 4

现在,让我们检查waitid()系统调用。该系统调用等待子进程更改状态。

#include <sys/wait.h>

int waitpid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

上面的系统调用等待子进程更改状态,此调用将挂起当前/调用进程,直到其任何子进程更改其状态为止。参数" infop"用于记录子进程的当前状态。如果进程已更改其状态,则此调用将立即返回。

idtype的值可以是以下任一个-

  • P_PID                  -  等待任何进程ID等于id的子进程。

  • P_PGID               -  等待任何子进程,其进程组ID等于id。

  • P_ALL                  -  等待任何子进程,并且id被忽略。

  • WCONTINUED  -  返回已停止并已继续的任何子代的状态。

  • WEXITED           -  等待进程退出。

  • WNOHANG        - 立即返回。

  • WSTOPPED        -  等待接收到信号的任何子进程停止,并返回状态。

如果由于其子项之一的状态更改而返回并且使用WNOHANG,则此调用返回0。如果出现错误,它将返回–1,并设置适当的错误编号。

/*文件名:waitid_test.c * /

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

int main() {
   int pid;
   int pids[3];
   int status;
   int numprocesses = 0;
   int total_processes = 3;
   siginfo_t siginfo;
   while (numprocesses < total_processes) {
      pid = fork();
      
      //Child process
      if (pid == 0) {
         printf("In child process: process id is %d\n", getpid());
         sleep(5);
         return 2;
      } else {
         pids[numprocesses] = pid;
         numprocesses++;
         printf("In parent process: created process number: %d\n", pid);
      }
   }
   
   //Waiting for 3rd child process
   status = waitid(P_PID, pids[total_processes - 1], &siginfo, WEXITED);
   if (status == -1) {
      perror("waitid error");
      return 1;
   }
   printf("Info received from waitid is: ");
   printf("PID of child: %d, real user id of child: %d\n", siginfo.si_pid, siginfo.si_uid);
   return 0;
}

执行并编译上述程序后,输出如下。

In child process: process id is 35390
In parent process: created process number: 35390
In child process: process id is 35391
In parent process: created process number: 35390
In parent process: created process number: 35391
In child process: process id is 35392
In parent process: created process number: 35390
In parent process: created process number: 35391
In parent process: created process number: 35392
Info received from waitid is: PID of child: 35392, real user id of child: 4581875

进程 - 子进程监控 - 无涯教程网无涯教程网提供正如我们所看到的,每当我们使用fork从程序创建子进程时,都会发生以下情况- 当前进程...https://www.learnfk.com/process/inter-process-communication-child-process-monitoring.html

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

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

相关文章

业财融合背景下,全面预算管理的发展之路

随着社会经济的高速发展&#xff0c;单一的组织机构职能极大限制了企业发展的创新动能。业务壁垒的不断滋生造成了信息传达严重的不对等&#xff0c;沟通协作成本加大&#xff0c;业务效率降低&#xff0c;专业化的分工形式逐渐成为了制约企业发展的桎梏。 2016年&…

基于Python科研论文绘制学习 - task3

Seaborn seaborn 在matplotlib 的基础上进行了更高级的封装&#xff0c;能用更少的代码绘制配图。 1、图类型 关系型图 数据分布型图 分类数据型图 回归模型分析图 2、多子图网格型图 FacetGrid&#xff08;&#xff09; import pandas as pd import numpy as np…

全球纳米烧结银市场年复合增长率为6.5%!

烧结银简单来讲是指经过低温烧结技术将纳米银粉&#xff08;平均粒径<0.1μm(100nm)&#xff09;印刷在承印物上&#xff0c;使之成为具有传导电流和排除积累静电荷能力的银浆&#xff0c;其由导电填料——银粉、粘合剂、溶剂及改善性能的微量添加剂组成&#xff0c;使用低熔…

云企业网CEN与转发路由器TR

云企业网CEN 云企业网CEN&#xff08;Cloud Enterprise Network&#xff09;是运行在阿里云私有全球网络上的一张高可用网络。云企业网通过转发路由器TR&#xff08;Transit Router&#xff09;帮助您在跨地域专有网络之间&#xff0c;专有网络与本地数据中心间搭建私网通信通…

苹果手机数据恢复的详细教程,果粉必看!

“照片不小心误删”、“清理内存把聊天记录删除了”、“手机重要文件丢失”……大家是否也会遇到以上的糟糕情况呢&#xff1f;“手机数据丢失”这六个字的杀伤力有多大&#xff0c;大家可想而知。 那么&#xff0c;手机删除的数据能够恢复吗&#xff1f;苹果手机数据恢复的方…

Hadoop Yarn 核心调优参数

文章目录 测试集群环境说明Yarn 核心配置参数1. 调度器选择2. ResourceManager 调度器处理线程数量设置3. 是否启用节点功能的自动检测设置4. 是否将逻辑处理器当作物理核心处理器5. 设置物理核心到虚拟核心的转换乘数6. 设置 NodeManager 使用的内存量7. 设置 NodeManager 节点…

光伏发电储能方案(小城光伏电站的智慧节能之路)

​阳光城小城光伏电站位于某省郊区,建成于5年前,总装机100兆瓦。电站采用光伏组串并联方式,将太阳能转换为电力后并网发电。但受限于光照条件,发电量经常无法有效利用,浪费严重。 为实现清洁能源的充分应用,电站管理层决定改造储能系统。经评估,采用联合电站侧、电网侧储能方式…

Java之内部类的详解

3.1 概述 3.1.1 什么是内部类 将一个类A定义在另一个类B里面&#xff0c;里面的那个类A就称为内部类&#xff0c;B则称为外部类。可以把内部类理解成寄生&#xff0c;外部类理解成宿主。 3.1.2 什么时候使用内部类 一个事物内部还有一个独立的事物&#xff0c;内部的事物脱…

Pytorch-day08-模型进阶训练技巧

PyTorch 模型进阶训练技巧 自定义损失函数 如 cross_entropy L2正则化动态调整学习率 如每十次 *0.1 典型案例&#xff1a;loss上下震荡 1、自定义损失函数 1、PyTorch已经提供了很多常用的损失函数&#xff0c;但是有些非通用的损失函数并未提供&#xff0c;比如&#xf…

4.7 为什么 TCP 每次建立连接时,初始化序列号都要不一样呢?

主要原因是为了防止历史报文被下一个相同四元组的连接接收。 如果正常通过四次挥手完成&#xff0c;TIME_WAIT状态会持续2MSL&#xff0c;历史报文会在下一个连接之前就自然消失&#xff0c;但无法保证每次连接都能通过四次挥手正常关闭。 假设客户端和服务端建立一个连接后&a…

Unity项目如何上传Gitee仓库

前言 最近Unity项目比较多&#xff0c;我都是把Unity项目上传到Gitee中去&#xff0c;GitHub的话我用的少&#xff0c;可能我还是更喜欢Gitee吧&#xff0c;毕竟Gitee仓库用起来更加方便&#xff0c;注意Unity项目上传时最佳的方式是把 Asste ProjectSetting 两个文件夹上传上…

基于redisson实现延时队列解耦业务

前言 今天跟大家分享的是一个基于redisson实现的延时队列&#xff0c;有个初版的封装工具&#xff0c;使用者只用关心延时时间到了取到的数据处理&#xff08;或者之前处理&#xff0c;到时间只做剩下的业务&#xff09;&#xff0c;废话不多说&#xff0c;直接上货。 一、业务…

目前电视盒子哪个最好?2023公认最佳电视盒子排名TOP5

电视盒子作为我们看片必备&#xff0c;功能更加丰富&#xff0c;看视频、玩游戏、K歌、上网课等都能实现&#xff0c;新手们在下单前会参考排行榜&#xff0c;近期业内发布了公认最好的电视盒子排名前五&#xff0c;不懂目前电视盒子哪个最好可以从入围的品牌中选择&#xff1a…

IET独立出版 | EI检索 | 2023年第三届机械、航空航天与汽车工程国际会议

会议简介 Brief Introduction 2023年第三届机械、航空航天与汽车工程国际会议&#xff08;CMAAE 2023&#xff09; 会议时间&#xff1a;2023年12月8 -10日 召开地点&#xff1a;中国南京 大会官网&#xff1a;www.cmaae.org 航天是当今世界最具挑战性和广泛带动性的高技术领域…

RTSP流媒体服务器EasyNVR视频平台设备通道时间与服务器录像时间不一致的问题解决步骤

EasyNVR平台优秀的视频能力在于通过RTSP/ONVIF协议&#xff0c;将前端接入设备的音视频资源进行采集&#xff0c;并转码成适合全平台、全终端分发的视频流格式&#xff0c;包括RTMP、RTSP、FLV、HLS、WebRTC等格式。平台已经在智慧水利、智慧工厂、智慧校园、智慧仓储等场景中应…

【解决】idea启动spring MVC报错:一个或多个listeners启动失败Listener ClassNotFoundException

idea配置教程。tomcat调试报错Artifact :war exploded: Error during artifact deployment。 修改代码后&#xff0c;启动不生效&#xff0c;仍是旧代码。 根本原因是&#xff1a; Modules output path和Artifacts output directory不匹配 Modules output path一定要等于Ar…

软件测试框架实战:Python+Slenium搭建Web自动化测试框架全教程

PythonSelenium是一种流行的Web自动化测试框架&#xff0c;可以模拟真实的用户操作&#xff0c;对网页进行功能和样式的验证。要通过selenium测试网页&#xff0c;需要以下几个步骤&#xff1a; 安装selenium库和浏览器驱动 。 使用selenium提供的方法来控制浏览器窗口大小、后…

如何建立自己的微信公众号

微信公众号是生活中常见的一种媒体形式&#xff0c;可以通过注册的方式来建立自己的微信公众号。 怎么注册 微信公众号注册的具体步骤如下&#xff1a; 1、在浏览器中搜索微信公众号&#xff0c;接着单击进入微信公众平台。 2、进入微信公众平台官网界面&#xff0c;接着单击…

【Acwing291】蒙德里安的梦想(状态压缩dp)详细讲解

题目描述 题目分析 显而易见的重要事实 首先&#xff0c;需要明白一个很重要的事实&#xff1a; 所有的摆放方案数所有横着摆放且合理的方案数 这是因为&#xff0c;横着的确定之后&#xff0c;竖着的一定会被唯一确定&#xff0c;举一个例子&#xff1a; ------唯一确定-…

自动化测试定位不到元素?可能是 frame 在搞鬼

很多人在用Splinter或Selenium定位页面元素的时候会遇到定位不到的问题&#xff0c;明明元素就在那儿&#xff0c;就是定位不到&#xff0c;这种情况很有可能是frame在搞鬼。 说白了就是网站上的网页A&#xff0c;又嵌入了其他网页B。你访问了网页A&#xff0c;在里面可以看到…