概念
守护进程又叫精灵进程(Daemon Process),它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
进程组:进程集合,每个进程组都有一个组长,其进程ID就是该进程组ID
会话:进程组集合,每个会话都有一个组长,其进程ID就是会话组ID
控制终端: 每个会话都可以有一个单独的控制终端,与控制终端连接的会话领头进程称为控制进程

特点
始终在后台运行,独立于任何终端,周期性的执行某种任务或等待处理特定事件。
它是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。
举例:
http 服务的守护进程叫 httpd,mysql 服务的守护进程叫 mysqld
守护进程的创建
方式1:
更简便地创建守护进程: nohup 命令
nohup xxxx &
nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。
nohup 命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。
方式2:
第一步:创建子进程,父进程退出
if(fork( ) > 0) { exit(0); }
//子进程变成孤儿进程,被init收养;子进程在后台运行
第二步:子进程创建新会话
if (setsid() < 0) { exit(0); }
//子进程成为新的会话组长;子进程脱离原来的终端
第三步:更改当前工作目录
chdir("/tmp");
//守护进程一直在后台运行,其工作目录不能被卸载;重新设置当前工作目录
第四步:重新设置文件权限掩码
if(umask(0) < 0) { exit(-1); }
//文件权限掩码设置为0,只影响当前进程
第五步:关闭打开的文件描述符
int i;
for(i = 0;i < 3;i++) { close(i); }
//关闭所有从父进程继承的打开文件;已脱离终端,stdin/stdout/stderr无法在使用
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
pid_t pid;
pid = fork();
if(pid < 0){
perror("fork");
return 0;
}else if(pid > 0){
exit(0);
// sleep(100);
}
printf("I am a deamon\n");
printf("sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));
if(setsid()<0){
perror("setsid");
exit(0);
}
printf("after sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));
chdir("/");
if(umask(0)<0){
perror("umask");
exit(0);
}
int i;
for(i=0;i<3;i++){
close(i);
}
printf("after close\n");
sleep(100);
return 0;
}
738

被折叠的 条评论
为什么被折叠?



