后端与 守护、僵尸进程| 青训营笔记

97 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第2天

Linux Daemon (守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。***

1.3.2 如何创建守护进程: ⭐⭐****

守护进程就是在后台运行 , 不与任何终端关联的进程 , 通常情况下守护进程在系统启动时就在运行 , 它们以 root 用户或者其他特殊用户 (apache postfix) 运行 , 并能处理一些系统级的任务。****

守护进程(daemon)详解与创建 - 简书 (jianshu.com)****

https://product.pconline.com.cn/itbk/software/dnyw/1435/14356628.html****


1.3.3 正确处理僵尸进程的方法 ⭐⭐⭐⭐****

1. 子进程退出时向父进程发送 SIGCHILD 信号,父进程处理 SIGCHILD 信号。在信号处理函数中调用 wait 进行处理僵尸进程。****

2. 把父进程杀掉。父进程死后,僵尸进程成为 " 孤儿进程 " ,过继给进程 init init 始终会负责清理僵尸进程。它产生的所有僵尸进程也跟着消失。****

3. fork 两次,父进程 fork 一个子进程,然后继续工作,子进程 fork ****个孙进程后退出,那么孙进程被 init 接管,孙进程结束后, init 会回收。不过子进程的回收 还要自己做。

两次 fork 的原理是将子进程成为孤儿进程,从而其的父进程变为 init 进程,通过 init 进程可以处理僵尸进程。****


wait 会令调用者阻塞直至某个子进程终止;****


waitpid 则可以通过设置一个选项来设置为非阻塞,另外 waitpid 并不是等待第一个结束的进程而是等待参数中 pid 指定的进程****


**#include<stdio.h>**

**#include<stdlib.h>**

**#include<signal.h>**

**#include<unistd.h>**

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

****

**void handler(int sig)**

**{**

**void(sig);**

**pid_t id;**

**while((id = waitpid(-1, NULL, WNOHANG)) > 0)**

**printf(“wait child success : %d\n”, id);**

**}**

****

**int main()**

**{**

**signal(SIGCHLD, handler);**

**pid_t ret = fork();**

**if(ret == 0)**

**{**

**printf(“child : %d\n”, getpid());**

**sleep(3);**

**exit(0);**

**}**

****

**while(1)**

**{**

**printf(“father process is doing some thing!\n”);**

**sleep(1);**

**}**

**return 0;**

**}**

当接收到一个类型为 sig 的信号时,就执行 handler 所指定的函数。( int signum 是传递给它的唯一参数。执行了 signal() 调用后,进程只要接收到类型为 sig 的信号,不管其正在执行程序的哪一部分,就立即执行 func() 函数。当 func() 函数执行结束后,控制权返回进程被中断的那一点继续执行。****