守护进程
特点:后台运行,没有控制终端。
常见的系统守护进程:
keventd:为在内核中运行 计划执行的函数 提供进程上下文。
kapmd:对计算机系统中具有的高级电源管理提供支持。
kswapd(pageout daemon):页面调出守护进程,它通过将脏页面以低速写到磁盘上,从而使这些页面在需要时仍可回收使用。即页面回收。
bdflush:将脏缓冲区从缓冲池(cache buffer)中冲洗到磁盘上。即cache回收。
Kupdated:每隔一定时间间隔,将脏页面冲洗到磁盘上,以便系统在失效时减少丢失的数据。
portmap:端口映射,将RPC(Remote procedure call,远程过程调用)程序号映射为网络端口号。
syslogd:记录系统日志
xinetd:侦听系统网络接口,以便取得来自网络的对各种网络服务进程的请求。
nfsd,lockd,rpciod提供对网络文件系统的支持。
cron:在指定的日期和时间执行指定的命令。
大多数守护进程都以超级用户(用户id为0)特权运行。没有一个守护进程具有控制终端,其终端名设置为问号(?),终端前台进程组ID设置为-1.
父进程ID为0的各进程通常为内核进程,进程1通常是init。
编写守护进程的步骤:
1. 设置文件模式创建屏蔽字;
umask(0);清除文件模式创建屏蔽字
2. fork;
调用fork(),接着让父进程退出
3. setsid;
setsid()设置session leader and process group leader
4. chdir;
chdir("/"),更改当前工作目录为根目录
5. close fd;
关闭从父进程进程的文件描述符
6. 打开/dev/null使其具有fd 0 1 2;
禁掉交互
禁掉fd 0,1,2后,进程出错怎样跟踪呢,可以通过syslog记录守护进程的信息。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <sys/resource.h> 6 #include <unistd.h> 7 #include <fcntl.h> 8 #include <string.h> 9 10 #define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 11 12 int main(int argc, char** argv) 13 { 14 int i, fd0, fd1, fd2, fd; 15 pid_t pid; 16 pid_t sid; 17 struct rlimit rl; 18 char acCwd[128]={0}; 19 20 //1. clear file creation mask 21 umask(0); 22 //2. fork() 23 pid = fork(); 24 if (pid < 0) 25 { 26 printf("fork error "); 27 exit(1); 28 } 29 else if (pid != 0) 30 exit(0); 31 32 printf("child process ID:%d ", getpid()); 33 //3. setsid() 34 sid = setsid(); 35 printf("child process session ID:%d ", sid); 36 //4. chdir() 37 printf("cwd real len:%d", getcwd(acCwd, 128)); 38 printf(" path:%s ", acCwd); 39 if (chdir("/") < 0) 40 { 41 printf("can't change current work dir "); 42 exit(1); 43 } 44 memset(acCwd, '