守护进程

本文介绍了Linux守护进程的特征,包括没有控制终端、在系统启动时启动等,并详细讲解了两种编写守护进程的方法,包括改变文件模式创建屏蔽字、创建新会话、改变工作目录、关闭文件描述符等步骤。此外,还提到了处理SIGCHLD信号以避免僵尸进程,以及实现单实例守护进程的方法,如使用记录锁。最后,文章解释了为何守护进程需要进行两次fork操作,以确保完全脱离终端并防止误操作。
摘要由CSDN通过智能技术生成

守护进程特征:

  • 没有控制终端
  • 经常在系统引导启动时启动,仅在系统关闭时终止
  • 守护进程的父进程是1号进程,在ubuntu 14.4上面用户守护进程的父进程不一定是1号进程,系统给用户空间分配了一个类似于1号进程的init–>user进程,进程号不一定

编写守护进程

方式一:

  1. 首先调用umask将文件模式创建屏蔽字设置为一个已知值(通常是0)

    因为继承而来的文件模式创建屏蔽字很可能会被设置为拒绝某些权限。如果守护进程要创建文件,那么它可能需要设置特定的权限。

  2. 然后调用fork,然后使父进程exit。这样做实现了下面几点:

    • 如果该守护进程是作为一条简单shell命令启动的,那么父进程终止会让shell认为这条命令已经执行完毕,不占用终端。

    • 子进程继承了父进程的进程组ID,获得了一个新的进程ID,这就保证了子进程不是一个进程组的组长ID,这就是后面的setsid调用的先决条件

  3. 然后调用setsid创建一个新会话。执行完setsid之后,调用进程将成为:

    • 新会话的首进程,

    • 是一个新进程组的组长进程,

    • 同时没有控制终端

  4. 将当前工作目录改为根目录/

    这是因为守护进程要求在系统重启/关闭之前是一直存在的。所以如果守护进程的当前工作目录在一个挂载的文件系统中,则该文件系统就不能被卸载。而从父进程中继承过来的当前工作目录可能就在一个挂在的文件系统中。

    • 当然某些守护进程可能会将当前工作目录更改到某个指定位置(不一定是/
  5. 关闭不再需要的文件描述符。这使得守护进程不再持有从其父进程继承而来的任何文件描述符。

    • 可以先判断最高文件描述符值,然后关闭直到该值的所有描述符

    • 使用getrlimit获得进程能够打开的最大文件数。

  6. 某些守护进程打开/dev/null/使其具有文件描述符0,1,2。这样任何试图读标准输入、写标准输出、写标准错误的库例程都不会产生任何效果。

    因为守护进程并不与任何终端关联,所以其输出无处显示,也无法获得用户的输入。

  7. 处理一些特殊的信号:SIGHUP,SIGTTIN,SIGTTOU,SIGCHLD,SIGTSTP

    守护进程一文中:
    但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源(关于僵尸进程的更多详情,请看《僵尸进程》)。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在 Linux 下可以简单地将 SIGCHLD 信号的操作设为 SIG_IGN 。关于信号的更详细用法,请看《信号中断处理》。
    注:通过忽略信号SIGCHLD,不关心子进程在结束的时候发出的信号,交由内核处理,不会产生僵死进程。

//只fork了一次
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
int main(){
    pid_t pid;
    struct rlimit r;

    umask(0);
    if((pid = fork()) < 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值