Daemon(精灵)进程,是linux中的后台服务进程,一般独立于控制终端而且周期性地执行某种任务或等待处理某些发生的时间。通常采用以d结尾的名字。从下面的进程信息能够看出,守护进程都是【?】。linux
colord 1160 0.0 0.2 399424 14520 ? Ssl 6月06 0:00 /usr/lib/colord/colord
Linux后台的一些系统服务进程,没有控制终端,不能直接和用户交互。不受用户登陆,注销的影响,一直在运做着,他们都是守护进程。如ftp服务器;nfs服务器等。shell
建立守护进程,最关键的一步是调用setsid函数建立一个新的会话(session),并成为session leader。服务器
会话比进程组更高一级,多个进程组对应一个会话。session
多个进程在同一个进出组,第一个进程是进程组的组长。函数
组长(父进程)不能够建立会话,必须是组员(子进程)建立。code
能够用【ps ajx】查看session id进程
1,建立会话的进程不能是组长进程(父进程)资源
2,建立会话成功的进程,变成组长进程(父进程)terminal
3,新会话的进程丢弃原来的终端控制get
4,创建新会话时,先调用fork,终止父进程,子进程调用建立会话的函数setsid
#include <sys/types.h> #include <unistd.h> pid_t setsid(void);
DESCRIPTION setsid() creates a new session if the calling process is not a process group leader. The calling process is the leader of the new session (i.e., its session ID is made the same as its process ID). The calling process also becomes the process group leader of a new process group in the session (i.e., its process group ID is made the same as its process ID). The calling process will be the only process in the new process group and in the new session.
Signal Value Action Comment ────────────────────────────────────────────────────────────────────── SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process
1,建立子进程,终止父进程
2,在子进程中调用函数setsid,来建立新会话
3,改变当前进程的目录。chdir函数
4,从新设置文件权限的掩码。umask函数
5,关闭0,1,2文件描述符。守护进程用不到0,1,2文件描述符。避免浪费资源。
6,开始执行守护进程的核心代码。
7,推出守护进程,通常执行不到这里,由于一直在循环里。
#include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <sys/time.h> #include <time.h> #include <signal.h> #include <stdlib.h> #include <stdio.h> #define _FILE_ "%s/log/data_%ld" void catc(int num){ char* host = getenv("HOME"); char buf[256] = {0}; sprintf(buf, _FILE_, host, time(NULL)); int fd = open(buf, O_WRONLY|O_CREAT, 0664); if(fd < 0){ perror("open:"); exit(1); } close(fd); } int main(){ //建立子进程 pid_t pid = fork(); //关闭父进程 if(pid > 0){ exit(0); } //建立新会话 setsid(); //设置掩码 umask(0); //改变工做目录 chdir(getenv("HOME")); //关闭文件描述符 close(0),close(1),close(2); //设置定时器 struct itimerval it = {{60, 0}, {1, 0}}; setitimer(ITIMER_REAL, &it, NULL); //捕捉信号SIGALRM struct sigaction act; act.sa_flags = 0; sigemptyset(&act.sa_mask); act.sa_handler = catc; sigaction(SIGALRM, &act, NULL); while(1) sleep(1); }
普通的进程也能强行变成守护进程。使用命令【nohup】。
它的做用是,阻塞信号SIGHUP,也就是当终端被关闭时,信号SIGHUP被阻塞了,因此进程就没有被终止。
nohup ./a.out >> a.log &
命令解释: