首页 > 系统相关 >无涯教程-进程 - 子进程监控

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

时间:2023-08-26 17:32:42浏览次数:36  
标签:教程 00 process pid 无涯 进程 sbin klogd

正如我们所看到的,每当我们使用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

参考链接

https://www.learnfk.com/process/inter-process-communication-child-process-monitoring.html

标签:教程,00,process,pid,无涯,进程,sbin,klogd
From: https://blog.51cto.com/u_14033984/7245547

相关文章

  • AI绘画StableDiffusion美女实操教程:斗破苍穹-小医仙
    之前分享过StableDiffusion的入门到精通教程:AI绘画:StableDiffusion终极炼丹宝典:从入门到精通但是还有人就问:安装是安装好了,可是为什么生成的图片和你生成的图片差距那么远呢?怎么真实感和质感一个天一个地呢?出图效果展示:那么,我画的图,和你画的图,差别在哪里呢?很关键的因素,就......
  • WebStorm2023 Windows激活教程(亲测有效)
    写在前面Webstorm目前已经更新到最新的2023.2版本了,许多小伙伴私聊问我,为啥之前2021.3.1的激活套路对新版本2023.2不管用了,是个什么情况?很显然,Webstorm官方发现了这种激活路数,新版本加入了更严厉的反制激活。所以说,小伙伴们激活成功了以后,尽量不要升级Webstorm,不然大......
  • 无涯教程-进程 - 镜像
    现在,我们已经了解了如何获取进程及其父进程的基本信息,是时候来研究进程信息的细节了。以下是进程镜像的图形表示。进程镜像(ProcessImage)到底是什么?进程镜像是执行程序时所需的可执行文件,该镜像通常包含以下部分-代码段或文本片段(Codesegmentortextsegment)数据段(Da......
  • 【Matlab 教程】-02 Matlab 基本操作与矩阵输入
    1、Matlab2020a界面简介2、命令行窗口1、操作符+-*/^在命令行窗口,输入表达式并回车计算,结果会以ans作为默认变量名,也可以在工作区查看优先级:()>^>*/>+-点击查看操作符+-*/^代码>>2+1ans=3 2+12-12/32*32^32、练习注意l......
  • 无涯教程-进程 - 信息
    在进入进程信息之前,我们需要了解一些事情,例如-  什么是进程? 进程是正在执行的程序。  什么是程序? 程序是一个文件,其中包含进程的信息以及在运行时如何进行构建。当您开始执行程序时,它将被加载到RAM中并开始执行。每个进程都用唯一的正整数标识,称为进程ID或简......
  • Webstorm 免费激活教程(2023最新,亲测有效)
    Webstorm是jetbrains公司旗下一款JavaScript开发工具。被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScriptIDE”等。Webstorm目前已经更新到最新的2023.2版本了,许多小伙伴私聊问我,为啥之前2021.3.1的激活套路对新版本2023.2......
  • Webstorm 最新激活教程,亲测有效
    本激活教程适用Windows/Mac/Linux系统,文中以Windows系统为例做讲解,其他系统按照教程顺序即可。下载最新的Webstorm2023.2版本安装包我们先从Webstorm官网下载Webstorm2023.2版本的安装包,下载链接如下:https://www.jetbrains.com/webstorm/download点击下载,静心等待......
  • 无涯教程-Python - XML处理
    XML是一种可移植的开放源语言,它使程序员能够开发可由其他应用程序读取的应用程序,而无需考虑操作系统和/或开发语言。可扩展标签语言(XML)是一种类似于HTML或SGML的标签语言。万维网联盟建议这样做,并且可以作为开放标准使用。XML对跟踪少量到中等数量的数据而无需基于SQL的主干......
  • 【Matlab 教程】-01 简介
    1、背景介绍MatrixLaboratory高级编程语言许多有用的toolboxs和内置functions简单的可视化2、课程目标如何使用Matlab编写程序,通过大量实践、实验解决工程上的问题3、课程计划1.简介2.Matlab基本操作与矩阵输入3.结构化程式与自定函数4.变量与文件存......
  • Webstorm2023 下载(附图文激活教程,亲测有效)
    笔者几乎试了网上几乎所有的Webstorm激活方案,发现这种靠谱的激活方法,先上图。第一步:下载最新的Webstorm2023.2版本安装包我们先从Webstorm官网下载Webstorm2023.2版本的安装包,下载链接如下:https://www.jetbrains.com/webstorm/download点击下载,静心等待其下载完......