您的位置:首页 > 其它

守护进程的创建过程

2017-06-08 11:11 155 查看
守护进程也称精灵进程(Daemon),是运行在后台的⼀一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是⼀一种很有用的进程。Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond等

Linux系统启动时会启动很多系统服务进程,这些系统服 务进程没有控制终端,不能直接和用户交互。其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时止,但系统服务进程不受用户登录注销的影响,它们⼀一直在运行着。这种进程⼀一个名称叫守护进程(Daemon)。

守护进程自成进程组自成会话,所以创建一个守护进程时必须先创建一个新的会话

Linux中用以下函数创建会话



该函数调用成功时返回新创建的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一个新进程,父进程退出 原因:1)如果该守护进程是作为一条简单的shell命令启动的,那么父进程终⽌止使得shell认为该命令已经执⾏行完毕 2) 保证子进程不是一个进程组的组长

3.调用setsid创建一个新会话结果是:1)该进程成为会话首进程 2)调用进程成为进程组的组长进程 3) 调用进程没有控制终端(再次fork 一次保证daemon不会打开终端)

4. 将工作目录改为根目录(chdir(“/”))原因:该守护进程是在当前工作目录下创建的默认工作目录是当前目录是一个相对路径,而守护进程自成会话独立运行在后台如果当前目录被删除该守护进程就会出错而根目录是不允许被删除的

5.关闭不需要的文件描述符(文件描述符也是一种资源释放不必要的资源)

6.忽略SIGCHLD(在一个进程终止或者停止时,将SIGCHLD信号发送给其父进程。按系统默认将忽略此信号。如果父进程希望被告知其子系统的这种状态,则应捕捉此信号,守护进程是一个孤儿进程不需要接收这个信号)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

void mydaemon()
{
umask(0);

pid_t id=fork();
if(id != 0)
{
exit(1);
}

if(0 > setsid())
{
return;
}

id=fork(); //会话首进程与终端关联再次fork与终端去关联
if(id<0)
return;
else if(id!=0)
exit(1);

if(chdir("/")<0){
printf("child dir error");
return;
}

signal(SIGCHLD,SIG_IGN);
close(0);
close(1);
close(2);
}

int main()
{
mydaemon();

while(1)
{}

return 0;
}




结果mydaemon自成自成会话自成进程组但不是会话首进程也不是进程组的组长没有与之关联的终端
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: