1、被我标题吸引进来的同学先不要着急,在讨论标题中的内容之前,我们需要先了解下进程的终止:

exit 与_exit 函数都是用来结束进程的函数,首先是exit:它的头文件:<stdlib.h> ,其次它用来正常结束当前进程,并把参数status返回给父进程,而进程所有的缓冲区数据也会自动写回并关闭未关闭的文件。而_exit 函数的头文件为:<unistd.h>,该函数会在结束进程时清空缓冲区。

2、僵尸进程:当一个进程的子进程挂了,父进程没有为它处理后事,那么这个子进程就会永远占用着进程描述符(ID),成为一个僵尸进程。

作为实例,我们来看一下这样一个程序:

int main()
{ int count = 10;while (count--){pid_t pid = fork();  switch (pid){case -1:perror ("fork");break;case 0:                 // 子进程printf ("我是子进程,我的Id 是%d\n", getpid());printf ("我走啦\n");exit(0);   // 子进程退出default:        // 父进程啥事也不干break;}}while(1);    // 父进程不退出return 0;
}

我们来看一下这样的一个程序运行之后,在" ps -ef | grep a.out " 之后我们能得到怎样的一个结果:

我们可以看到,在那10个a.out 的后面跟了“defunct”这样一个单词,笔者翻过词典发现,该单词的意思是“死者”,“死去的”。对,这就是10具尸体,然而它们却依旧跑在后台,想想都很恐怖啊。

那怎么将它们处理掉呢,这时候就需要它们的父进程来执行一下安葬函数了:

3、安葬函数:wait 和 waitpid

1)按照用户手册上,wait() 函数的参数应该是"int * status"这样的指针,但我们可以省略,用NULL也行。如果一个子进程已经终止,并且是一个僵死进程,wait立即返回并取得该子进程的状态,否则wait使其调用者阻塞直到一个子进程终止。如果调用者阻塞并且它有多个子进程,则在其一个子进程终止时,wait就立即返回。因为wait返回终止子进程的ID,所以总能了解到是哪一个子进程终止了。

2)waitpid() 函数的参数就很多样化,pid_t  waitpid (pid_t  pid,  int *status,  int  options) ,首先,是子进程识别码,我们可以填上之前fork() 函数的返回值即是子进程的ID,如果子进程太多,可以选用-1或0,-1则和wait() 相同,任何子进程都可以,0是等待与目前进程相同的任何子进程。然后,我们来看参数option,可以为0 或下面的OR 组合:
WNOHANG:      如果没有任何已经结束的子进程则马上返回,不予以等待。
WUNTRACED :如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。

3)最后我们来看一下它们的返回值和共同参数" int *status",关于它的返回值,成功则返回子程序的ID,出错则返回-1。另外的参数,需要我们传入一个地址,如果子进程正常结束,则参数的值变成0,但如果是被干掉的,则会变为15。当然,我们也可以利用这样一些宏:

WIFEXITED(status)
    若子进程正常终止,该宏返回true。
    此时,可以通过WEXITSTATUS(status)获取子进程的退出状态(exit status)。
 WIFSIGNALED(status)
    若子进程由信号杀死,该宏返回true。
    此时,可以通过WTERMSIG(status)获取使子进程终止的信号值。
 WIFSTOPPED(status)
    若子进程被信号暂停(stopped),该宏返回true。
    此时,可以通过WSTOPSIG(status)获取使子进程暂停的信号值。
 WIFCONTINUED(status)
    若子进程通过SIGCONT恢复,该宏返回true。

4、守护进程:

当父进程挂掉,子进程会被祖先进程(init)接收运行在后台,成为一个守护进程。库函数里提供了这样一个守护进程的创建函数:deamon() ,但这边,我们来手动创建一个:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>int daemonize(int nochdir, int noclose)
{// 1、创建子进程,关闭父进程pid_t pid = fork();if (pid > 0){exit(0);}else if (pid < 0){return -1;}// 2、设置文件的掩码, mode & ~umaskumask(0);// 3、设置新的会话: 脱离当前会话和终端的控制if (setsid() < 0){return -1;}if (nochdir == 0 ){// 4、改变当前的工作目录if (chdir("/") < 0){return -1;}}// 标准输入、关闭标准输出、标准错误close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);if (noclose == 0){// 重定向标准输入、关闭标准输出、标准错误open("/dev/null", O_RDONLY);   // 0 open("/dev/null", O_RDWR);   // 1open("/dev/null", O_RDWR);   // 2}return 0;
}

当然,上述创建方法完全可以由这样一句代码代替:

 daemon(0,0);

。。。。。。

琐记8:恐怖的僵尸进程与温暖的守护进程相关推荐

  1. Linux进程间关系之守护进程

    概念 守护进程也称精灵进程,是运行在后台的一种特殊进程.守护进程独立于控制终端并且周期性的执行某种任务或者等待处理某些打算的事件.可认为守护进程目的就是防止终端产生的一些信号让进程退出 特点 所有的守 ...

  2. linux守护进程以及如何编写守护进程程序

    守护进程 理论 「守护进程」是 Linux 的一种长期运行的后台服务进程,也有人称它为「精灵进程」.我们常见的 httpd.named.sshd 等服务都是以守护进程 Daemon 方式运行的,通常服 ...

  3. Python 多进程笔记 — 启动进程的方式、守护进程、进程间通信、进程池、进程池之间通信、多进程生产消费模型

    1 面向过程启动多进程 Python 操作进程的类都定义在 multiprocessing 模块,该模块提供了一个 Process 类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另 ...

  4. 小何讲进程: 编写Linux守护进程方法详解

    守护进程概述 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程. 它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些事件的发生. 守护进程常常在 ...

  5. 进程间关系和守护进程

    一. 进程组/作业/会话 1.进程组     每一个进程除了有一个进程ID之外, 还属于一个进程组. 进程是一个或多个进程的集合. 通常, 它们与同一个作业向关联, 可以接收来自同一个终端下的各种命令 ...

  6. Linux守护进程编程编写,linux守护进程编程实例

    /* *功能:创建一个守护进程,监视系统所有运行的进程 *时间:2013.4.14 */ #include #include #include #include #include #include # ...

  7. 主进程、子进程和守护进程

    理解 主进程main thread: 程序执行的入口,可以理解为常用的main 函数. 父进程parent thread: 对于子进程而言, 子进程的创造者,可有多个子进程. 任何进程都有父进程,追根 ...

  8. linux怎么监控守护进程,linux shell脚本守护进程监控svn服务

    最近搭建的svn服务不知道什么原因服务总是被关闭(如果你不知道怎么搭建svn可以参考linux下搭建svn版本控制软件),因此用shell脚本实现一个守护进程.用于监控svn服务是否启动,如果服务不在 ...

  9. php进程守护进程,php 多进程实现守护进程的实例代码

    /** * 入口函数 * 将此文件保存为 ProcessOpera.php * 在terminal中运行 /usr/local/php/bin/php ProcessOpera.php & * ...

最新文章

  1. java super快速生成_为什么当我使用编辑器代码生成器时,eclipse会在构造函数中自动添加一个java super()方法?...
  2. python中 pip的安装方法
  3. STM32(六)- 系统定时器
  4. Linux下的rsync远程增量备份详解
  5. 15-07-10 结构体-输入学生成绩进行排序
  6. ubuntu,kali linux和windows三系统流水账——写给自己
  7. 走近夜间灯光——教你平均灯光指数(ANLI)如何得到(超详细)
  8. Oracle 视图、序列、索引、游标、触发器、事务
  9. Java Thread 多线程 操作线程
  10. ubuntu20.04安装交叉编译工具链流程
  11. 本周赠书:卓有成效的工程师
  12. 我的ROS2开发环境
  13. html实现tab 左右滑动
  14. 怎么把vob格式的视频转换成mp4格式
  15. 2017计科01-08编译原理模拟测试2--chap03
  16. 【DB】数据库面试笔试题库及详解(小麦苗DBA宝典出品)--数据库运维宝典
  17. 计算机知识产权查询,如何查询版权登记、计算机软件著作权登记?
  18. Java中文生僻字排序
  19. hcia是什么等级的证书_HCIA是什么等级的证书
  20. 卡斯特:中国是一个全球化的大试验

热门文章

  1. 华为实验24-vRRP基本配置
  2. Java练习题-09
  3. 一些优秀的后端开源项目!
  4. 详解randn函数及 randn('state')
  5. Qt5 bug error c2001: 常量中有换行符
  6. 数字电路硬件设计系列(十三)之HDMI电路设计
  7. jupyter中interrupt the kernel(中断)没有反应
  8. 两个集合相等的例题_集合的相等答案
  9. Spring+SpringMVC+Mybatis简单整合 图书管理项目 实现增删改查
  10. 苹果电脑硬盘损坏数据是否可以恢复