守护进程(daemon)

守护进程也叫精灵进程(daemon):它独立于控制终端,并且周期性的执行某些操作或者等待某个任务,是一种很有用的进程。Linux下的服务器大多是由守护进程实现的,比如说web服务器,Internet服务器等等,守护进程不收终端登录和注销影响,他们是独立的,自成终端。

一、查看守护进程:
用命令 ps axj 查看进程,得到TPGID一列为-1,说明没有控制终端,就是所谓的守护进程。
这里写图片描述
二、守护进程的几个特点:
1.守护进程自成进程组,自成会话。
2.命名一般以D结尾,不受一般用户注销和登录影响。
3.是孤儿进程,该进程的pid是1,表示它被init领养。
4.守护进程一般实现服务器,不掉线。即使出现故障掉线了,也会立即重启。
三、创建守护进程:
1.创建守护进程的关键是调用setsid()函数来创建一个会话,并且成为会话的leader。

#include<unistd.h>
pid_t setsid(void);

该函数成功返回会话的id,其实也是进程的id。出错时返回-1。注意:调用时,当前进程不允许时进程组leader,否则返回-1。
为了保证当前进程不是进程组的leader,fork()一个进程,此时进程组包含两个进程,分别是子进程和,父进程,父进程是leader。此时在子进程里调用就可以保证当前进程不是进程组leader。
成功调用该函数的结果:
得到一个id这个id是session 的id。
创建了一个进程组,该id也是当前进程组的leader id。
2.创建守护进程:
①.用umask()来将文件模式创建屏蔽字设置为0,因为守护进程也可能创建文件,为使创建的文件不收umask限制。
②.调用fork(),并且使父进程exit()。因为要当前进程不是进程组leader,才能成功,上面讲过。
③.在子进程里调用setpid创建会话。
④当前工作目录修改为根目录。
⑤.关闭相关的文件描述符,0,1,2三个文件描述符。
⑥.忽略的SIGCHLD的信号。

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void Mydaemon()
{
    pid_t id;
    umask(0);
    id=fork();
    if(id>0)
   {
       exit(0);//父进程退出
   }
    setsid();
    chdir("/");
    close(0);
    close(1);
    close(2);
    signal(SIGCHLD,SIG_IGN);

}
int main()
{
   Mydaemon();
    while(1)
    sleep(1);
return 0;
}

运行结果:
这里写图片描述
产生一个守护进程。
系统自带的产生守护的方法:

#include<unistd.h>
int daemon(int nochdir,int noclose);

参数:默认修改目录,默认关闭文件描述符。

#include<unistdh>
#include<stdio.h>
void create_daemon()
{
daemon(0,0);//调用系统方法
}
int main()
{
craete_daemon();
while(1)
sleep(1);
return 0;
}

结果:
又创建了一个守护进程。
这里写图片描述
问题答疑:为什么有些人会fork()两次再产生守护进程?
这里有个假设,如果父进程fork()一次,产生守护进程,这时父进程没有安全退出,而守护进程还在继续运行。如果守护进程因为某种原因安全或者非安全退出了,这时守护进程不能被init领养,而变为zombie进程。
但是如果fork()两次,父进程fork()出子进程,子进程再fork()出孙子进程去执行创建守护进程。儿子进程立刻退出,守护进程会被init领养,变为孤儿进程,而父进程不管做任何事都与守护进程无关了。所以说,fork()两次的守护进程是进安全的,避免了僵尸进程的出现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值