守护进程概念
linux三种进程类型之一,是一个在后台运行并且不受任何终端控制的进程。它的生存期较长,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。
守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。
特点
① 始终在后台运行
② 独立于任何终端
③ 周期性的执行某种任务或等待处理特定事件
相关概念
进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。
会话(Session): 进程组集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。
控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。
![](https://img-blog.csdnimg.cn/img_convert/32276f7bca63341b84812b14a64c37ae.png)
守护进程的创建
3.1 创建子进程,父进程退出
if (fork() > 0) {
exit(0);
}
父进程退出后,子进程变成孤儿进程,被init进程收养, 子进程在后台运行。
3.2 子进程创建新会话
if (setsid() < 0) {
exit(-1);
}
子进程成为新的会话组长, 子进程脱离原先的终端。
3.3 更改当前工作目录
chdir(“/”);
chdir(“/tmp”);
守护进程一直在后台运行,其工作目录不能被卸载需要重新设定当前工作目录cwd。
3.4 重设文件权限掩码
if (umask(0) < 0) {
exit(-1);
}
文件权限掩码设置为0, 只影响当前进程。
3.5 关闭打开的文件描述符
int i;
for(i=0; i<3; i++) {
close(i);
}
关闭所有从父进程继承的打开文件,由于已脱离终端,所以stdin / stdout / stderr无法再使用。
例1
int main() {
pid_t pid;
FILE *fp;
time_t t;
int i;
if ((pid = fork()) < 0) {
perror(“fork”); exit(-1);
}
else if (pid > 0) {
exit(0);
}
setsid();
umask(0);
chdir(“/tmp”);
for (i=0; i< 3; i++) {
close(i);
}
if ((fp = fopen(“time.log”, “a”)) == NULL) {
perror(“fopen”); exit(-1); }
while ( 1 ) {
time(&t);
fprintf(fp, “%s”, ctime(&t));
fflush(fp);
sleep(1);
}