进程 - 其它进程

进程 - 其它进程 首页 / 进程通信入门教程 / 进程 - 其它进程

到目前为止,我们已经讨论了进程,进程的创建,父进程和子进程等。如果不讨论其他相关进程(如孤立进程,僵尸进程和守护进程),则将是不完整的。

孤立进程

当我们运行程序或应用程序时,该应用程序的父进程是shell,当我们使用fork()创建进程时,新创建的进程是子进程,而创建子进程的进程是父进程。反过来,其父进程是shell。当然,所有进程的父进程都是init进程(进程ID→1)。

以上是通常的情况,但是如果父进程在子进程之前退出,会发生什么情况,子进程变为孤立进程,让我们尝试使用以下示例来理解这一点。

/*文件名:orphan_process.c * /

#include<stdio.h>
#include<stdlib.h>

int main() {
   int pid;
   system("ps -f");
   pid = fork();
   if (pid == 0) {
      printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
      sleep(5);
      printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
      system("ps -f");
   } else {
      printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
      sleep(2);
      exit(0);
   }
   return 0;
}

编译和执行步骤

UID         PID   PPID  C STIME TTY    TIME CMD
4581875  180558      0  0 09:19  ?     00:00:00 sh -c cd /home/cg/root/4581875; 
                                       timeout 10s main
4581875  180564 180558  0 09:19  ?     00:00:00 timeout 10s main
4581875  180565 180564  0 09:19  ?     00:00:00 main
4581875  180566 180565  0 09:19  ?     00:00:00 ps -f
Parent: pid is 180565 and ppid is 180564
UID         PID   PPID  C STIME TTY    TIME CMD
4581875  180567      0  0 09:19  ?     00:00:00 main
4581875  180820 180567  0 09:19  ?     00:00:00 ps -f
Child: pid is 180567 and ppid is 180565
Child: pid is 180567 and ppid is 0

僵尸进程

简单来说,假设您有两个进程,即父进程和子进程,父进程有责任等待子进程,然后从进程表中清除子进程,如果父进程尚未准备好等待子进程,同时子进程完成其工作并退出,该怎么办?现在,子进程将变成僵尸进程。当然,在父进程准备就绪后,清理僵尸进程。

让我们借助示例来理解这一点。

/*文件名:zombie_process.c * /

#include<stdio.h>
#include<stdlib.h>

int main() {
   int pid;
   pid = fork();
   if (pid == 0) {
      system("ps -f");
      printf("Child: pid is %d and ppid is %d\n",getpid(),getppid());
      exit(0);
   } else {
      printf("Parent: pid is %d and ppid is %d\n",getpid(),getppid());
      sleep(10);
      system("ps aux|grep Z");
   }
   return 0;
}

编译和执行步骤

UID         PID   PPID  C STIME TTY    TIME CMD
4581875  184946      0  0 09:20  ?     00:00:00 sh -c cd /home/cg/root/4581875; 
                                       timeout 10s main
4581875  184952 184946  0 09:20  ?     00:00:00 timeout 10s main
4581875  184953 184952  0 09:20  ?     00:00:00 main
4581875  184954 184953  0 09:20  ?     00:00:00 main
4581875  184955 184954  0 09:20  ?     00:00:00 ps -f
Child: pid is 184954 and ppid is 184953

守护进程

简单来说,没有任何关联的shell或终端的进程称为守护进程,为什么需要这个?这些是在后台运行的进程,它们以预定义的时间间隔执行操作并响应某些事件,守护程序进程不应与任何用户交互,因为它作为后台进程运行。

无涯教程网

现在让我们看看如何创建守护进程。以下是步骤-

步骤1   -  创建一个子进程,现在我们有两个进程–父进程和子进程

    通常,进程层次结构为:SHELL→PARENT PROCESS→CHILD PROCESS

步骤2   -  通过退出终止父进程,现在子进程成为孤立进程,并由init进程接管。

    现在,层次结构是INIT PROCESS→CHILD PROCESS

步骤3   -  如果调用进程不是进程组负责人,则调用setsid()系统调用将创建一个新会话。

步骤4   -  将进程组ID和会话ID设置为调用进程的PID。

步骤5   -  由于终端和Shell现在已与应用程序断开连接,请关闭进程的默认文件描述符(标准输入,标准输出和标准错误)。

链接:https://www.learnfk.comhttps://www.learnfk.com/process/inter-process-communication-other-processes.html

来源:LearnFk无涯教程网

/*文件名:daemon_test.c * /

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char *argv[]) {
   pid_t pid;
   int counter;
   int fd;
   int max_iterations;
   char buffer[100];
   if (argc < 2)
   max_iterations = 5;
   else {
      max_iterations = atoi(argv[1]);
      if ( (max_iterations <= 0) || (max_iterations > 20) )
      max_iterations = 10;
   }
   pid = fork();
   
   //Unable to create child process
   if (pid < 0) {
      perror("fork error\n");
      exit(1);
   }
   
   //Child process
   if (pid == 0) {
      fd = open("/tmp/DAEMON.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
      if (fd == -1) {
         perror("daemon txt file open error\n");
         return 1;
      }
      printf("Child: pid is %d and ppid is %d\n", getpid(), getppid());
      printf("\nChild process before becoming session leader\n");
      sprintf(buffer, "ps -ef|grep %s", argv[0]);
      system(buffer);
      setsid();
      printf("\nChild process after becoming session leader\n");
      sprintf(buffer, "ps -ef|grep %s", argv[0]);
      system(buffer);
      close(STDIN_FILENO);
      close(STDOUT_FILENO);
      close(STDERR_FILENO);
   } else {
      printf("Parent: pid is %d and ppid is %d\n", getpid(), getppid());
      printf("Parent: Exiting\n");
      exit(0);
   }
   
   //Executing max_iteration times
   for (counter = 0; counter < max_iterations; counter++) {
      sprintf(buffer, "Daemon process: pid is %d and ppid is %d\n", getpid(), getppid());
      write(fd, buffer, strlen(buffer));
      sleep(2);
   }
   strcpy(buffer, "Done\n");
   write(fd, buffer, strlen(buffer));
   
   //Can't print this as file descriptors are already closed
   printf("DoneDone\n");
   close(fd);
   return 0;
}
Parent: pid is 193524 and ppid is 193523
Parent: Exiting
4581875  193525      0  0 09:23  ?      00:00:00 main
4581875  193526 193525  0 09:23  ?      00:00:00 sh -c ps -ef|grep main
4581875  193528 193526  0 09:23  ?      00:00:00 grep main
4581875  193525      0  0 09:23  ?      00:00:00 main
4581875  193529 193525  0 09:23  ?      00:00:00 sh -c ps -ef|grep main
4581875  193531 193529  0 09:23  ?      00:00:00 grep main

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

邱岳的产品实战 -〔邱岳〕

苏杰的产品创新课 -〔苏杰〕

分布式协议与算法实战 -〔韩健〕

流程型组织15讲 -〔蒋伟良〕

爆款文案修炼手册 -〔乐剑峰〕

中间件核心技术与实战 -〔丁威〕

Serverless进阶实战课 -〔静远〕

结构写作力 -〔李忠秋〕

云原生基础架构实战课 -〔潘野〕

好记忆不如烂笔头。留下您的足迹吧 :)