守护进程
概念:
守护进程也成精灵进程,是运行在后台的一种特殊的进程,也就是一个后台作业,独立于控制终端并且周期性的执行某种任务或者等待处理某些发生的事件。Linux系统启动时会启动很多系统服务进程,这些系统服务没有终端,不能直接和用户交互。其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,7*24小时一直运行。
特点:
(1)守护进程自成会话,自成进程组,与终端无关;
(2)守护进程本身是一种孤儿进程;
(3)守护进程命名以‘d’结尾;
(4)守护进程时7*24在线,提供服务;
(5)守护进程是大部分网络服务器的载体;
创建会话:
pid_t setsid(void);
特点:(1) 调用进程成为会话的首进程;
(2)调用进程成为一个进程组的组长进程;
(3)调用进程没有控制终端;
返回值:创建成功返回所创建进程的pid,创建失败返回-1;
例子:
#include<stdio.h>
void mydaemon()
{
umask(0);
pid_t id = fork();
if(id > 0)
{
exit(1);
}
setsid();
chdir("/");
close(0);
close(1);
close(2);
signal(SIGCHLD,SIG_IGN);
}
int main()
{
mydaemon();
while(1)
{}
return 0;
}
创建守护进程的关键步骤:
1.使用umask修改屏蔽字为0:当在守护进程中创建文件的时候,设置umask为0,那么所创建文件的权限就是创建的权限和系统没有关系
2.fork创建子进程:创建子进程并且关闭父进程,使得子进程成为孤儿进程被1号进程收养,使得该子进程自成会话。
3.修改工作路径:普通的后台作业是隶属于某个会话的,而守护进程是自成会话的。
4.关闭不需要的文件描述符:后台作业不能从标准输入读取数据,并且尽可能关闭从父进程继承过来的文件描述符;
5.忽略SIGCHLD信号;
为什么创建守护进程时有人fork两次?
(1)第一次fork:调用setsid的进程不能是进程组的组长进程,所以需要终止fork的父进程,使用子进程进行setsid创建会话。当终止了父进程之后、,该子进程成为孤儿进程被1号进程收养,且没有控制终端。
(2)第二次fork:在刚才子进程的基础上再创建一个子进程。因为当前子进程是一个进程组的组长进程,是可以去打开控制终端的前台,为了防止可以打开控制终端,我们可以再fork一个进程,那么该进程的pid 和当前会话的sid不一样,那么就不可能打开终端了,就可以在此进程下进行守护进程操作。
作者水平有限 ,若有问题,请留言,谢谢!!!