守护进程是工作在后台的程序,是用户"看不见"的进程,它们会在后台偷偷的运行着。
守护进程是不需要和控制台进行通信的,所以可以将标准输入、标准输出以及标准出错都关掉。
如何关掉呢?
调用库函数daemon就能达到这一需求,
#include <unistd.h>
int daemon(int nochdir, int noclose);
在daemon函数内部,它会将stdin、stdout以及stderr都关掉。
个人觉得:
所谓守护进程只是一种概念,并不一定是调用了daemon函数就是守护进程;
而未调用daemon函数就不是守护进程。
daemon函数是如何close掉stdin、stdout以及stderr的呢?
将stdin、stdout和stderr都重定向到黑洞文件/dev/null中。
int fd = open("/dev/null", O_RDWR, 0);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
其中系统调用open用来打开一个文件,并返回该文件的文件描述符,
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags, mode_t mode);
系统调用close用来关闭一个指定的文件,
#inlcude <unistd.h>
int close(int fd);
系统调用dup2用来将newfd对应的文件重定向到oldfd上。
这两个文件描述符共享同一个数据结构,这样对其中一个文件的操作会同时影响到这两个文件。
可以将newfd理解成一个指针,它指向oldfd指向的位置,这样无论是对newfd还是oldfd的操作都是一样的。
#include <unistd.h>
int dup2(int oldfd, int newfd);
系统独立运行的守护进程称之为stand alone daemon,常见的包括atd、crond、syslogd等。
和stand alone daemon相对的另一种就是super daemon。
比如inetd,它在后台监听网络端口,当接收到client端的请求时,它会根据请求的端口来
决定启动不同的网络服务程序。
另外一种分类的方法分为:signal control daemon和interval control daemon。
像inetd就属于signal control daemon;crond、syslogd等就属于interval control daemon。
守护进程还有很多,比如dhcpd、httpd、ntpd等等。
本篇就当先做个了解。