守护进程中fork一次与两次的区别

守护进程(daemon进程)是后台守护进程,有时候也叫精灵进程(agent).

linux 下server都是daemon进程。

其 特点 是:

1)其父进程是一号进程,通常以d结尾

2)在后台运行,独立于终端,周期性的以某种任务或等待处理某些发生的事

3)自成进程组,自成会话,不受登陆注销等影响

4)一般是孤儿进程

daemon函数存在的原因是因为控制终端由于某些原因(如断开终端链接)会发送一些信号的原因。而接收进程处理这些信号缺省动作会让进程退出。这些信号会由于终端上敲一些特殊按键而产生。

创建守护进程最关键 的⼀一步是 调⽤用setsid函数 创建⼀一个新的Session,并成为Session Leader。

该函数调⽤用成功时返回新创建的Session的id(其实也就是当前进程的id),出错返回-1。注意,调用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。要保证当前进程不 是进程组的Leader也很容易,只要先fork再调用setsid就行了。fork创建的子进程和父进程在同 ⼀一个进程组中,进程组的Leader必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,在子进程中调⽤用setsid就不会有问题了。

成功调用该函数的结果是:

1. 创建⼀一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id。

2. 创建⼀一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。

3. 如果当前进程原本有⼀一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进 程。所谓失去控制终端是指,原来的控制终端仍然是打开的,仍然可以读写,但只是一个普通的打开文件而不是控制终端了。

创建守护进程

1. 调用umask将文件模式创建屏蔽字设置为0.

2. 调用fork,父进程退出(exit)。原因:1)如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止使得shell认为该命令已经执行完毕。2)保证子进程不是一个进程组的组长进程。

3. 调用setsid创建⼀一个新会话。setsid会导致:1)调用进程成为新会话的⾸首进程。 2)调用 进程成为一个进程组的组长进程 。3)调用进程没有控制终端。(再次fork⼀一次,保证 daemon进程,之后不会打开tty设备)

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

5. 关闭不在需要的文件描述符。

6. 其他:忽略SIGCHLD信号

了解详细守护进程创建内容点击打开链接

创建简易的守护进程(两次fork())

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<signal.h>
void mydaemon()
{
    umask(0);//1
    if(fork()>0)//2
        exit(1);   
    setsid();//3
    if(fork()>0)
        exit(1);       
    chdir("/");//4
    close(0);//5
    close(1);
    close(2);
    signal(SIGCHLD,SIG_IGN);//6
}
int main()
{
    mydaemon();
    while(1)
    {
        sleep(1);
    }
    return 0;
}

使用ps axj查看系统中的所有进程,通过管道过滤出自己创建的守护进程,可以发现进程组id和会话id都与pid不同。


1 、第一次fork的作用是让shell 认为本条命令 已经终止,不用挂在终端输入上。还有一个作用是为后面setsid服务。setsid的调用者不能是进程组组长(group leader). 此时父进程是进程组组长。

2 、setsid() 是本函数最重要的一个调用。它完成了daemon函数想要做的大部分事情。调用完整个函数。子进程是会话组长(sid==pid),也是进程组组长(pgid == pid),并且脱离了原来控制终端。到了这一步,基本上不管控制终端如何怎么样。新的进程都不会收到那些信号。

3  、经过前面2个步骤,基本想要做的都做了。第2次fork不是必须的。也看到很多开源服务没有fork第二次。fork第二次主要目的是。防止进程再次打开一个控制终端。因为打开一个控制终端的前台条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。所以也无法打开新的控制终端。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值