守护进程,又称为精灵进程(Daemon),是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或者是等待处理某些发生的事情。守护进程是一种孤儿进程,且守护进程自成进程组、自成会话,且通常采用d结尾的名字,表示Deamon。
特点:
1)守护进程没有控制终端,不能直接和用户交互;
2)守护进程不受用户登录注销的影响,且一直在运行着。
1.查看守护进程
我们可以用ps axj命令来查看系统中的进程(参数a表示列出所有用户的进程;参数x表示不管有无终端控制的进程;参数j表示列出与作业控制有关的信息),如下图所示:
凡是TPGID一列标为-1的进程均为守护进程,凡是TTY一列标为?的进程均为守护进程。
2.创建守护进程
采用如图所示的函数即可创建出守护进程。该函数调用成功时返回新创建的Session的id,出错返回-1。
注:调用该函数前,当前进程不允许是进程组的组长进程。
创建步骤:
1) 调用umask将文件模式创建屏蔽字设置为0;
2)调用fork函数,使父进程退出;
原因:保证子进程不是一个进程组的组长进程。
3)调用setsid创建一个新会话; (此步骤是整个过程中最关键的一步)
现象:a)调用进程成为新会话的首进程
b)调用进程成为一个进程组的组长进程
c)调用进程没有终端控制
4)将当前工作目录更改为根目录;
5)关闭不需要的文件描述符
6)忽略SIGCHLD信号
相关源代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void mydaemon() {
//文件模式的创建屏蔽子设置为0
umask(0);
//fork之后,父进程退出
if(fork() > 0) {
exit(1);
}
//调用setsid创建一个新会话
setsid();
//更改目录为根目录
chdir("/");
//关闭不需要的文件描述符
close(0);
close(1);
close(2);
//忽略SIGCHID信号
signal(SIGCHLD, SIG_IGN);
}
int main() {
mydaemon();
while(1);
return 0;
}
运行结果如下:
3.删除守护进程
删除守护进程的方法特别简单,调用kill函数即可。如下图所示。