Node 守护进程

# 何为守护进程

Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。

# 守护进程创建流程

  1. 创建进程a
  2. 在进程a中创建子进程b(多用fork()函数)
  3. 对进程b执行setsid方法
  4. 进程a退出, 进程b由init进程接管, 此时进程b为守护进程

# setsid 详解

  1. 该进程变成一个新会话的会话领导。
  2. 该进程变成一个新进程组的组长。
  3. 该进程没有控制终端。

# 创建子进程并调用setsid

1
2
3
4
5
6
7
8
9
var spawn = require('child_process').spawn;
var process = require('process');

var p = spawn('node',['b.js'], {
  detached: true, // 创建子进程, 并调用setsid函数, 
  stdio: 'ignore'
});
console.log(process.pid, p.pid);
process.exit(0);  // 退出父进程, 子进程由init进程接管
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// b.js
var fs = require('fs');
var process = require('process');

fs.open("/Users/xxx/Desktop/log.txt",'w',function(err, fd){
	console.log(fd);
	while(true)
	{
		fs.write(fd,process.pid+"\n",function(){});
	}
});

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 守护进程实现 (C语言版本)
void init_daemon()
{
    pid_t pid;
    int i = 0;

    if ((pid = fork()) == -1) {
        printf("Fork error !\n");
        exit(1);
    }

    if (pid != 0) {
        exit(0);        // 父进程退出
    }

    setsid();           // 子进程开启新会话, 并成为会话首进程和组长进程
    if ((pid = fork()) == -1) {
        printf("Fork error !\n");
        exit(-1);
    }
    if (pid != 0) {
        exit(0);        // 结束第一子进程, 第二子进程不再是会话首进程
                        // 避免当前会话组重新与tty连接
    }
    chdir("/tmp");      // 改变工作目录
    umask(0);           // 重设文件掩码
    for (; i < getdtablesize(); ++i) {
       close(i);        // 关闭打开的文件描述符
    }

    return;
}
Licensed under CC BY-NC-SA 4.0