目录
一、守护进程的引入
1、进程查看命令ps
(1)ps -ajx 偏向显示各种有关的ID号
(2)ps -aux 偏向显示进程各种占用资源
2、向进程发送信号指令kill
(1)kill -信号编号 进程ID,向一个进程发送一个信号
(2)kill -9 xxx,将向xxx这个进程发送9号信号,也就是要结束进程
系统有很多d结尾的进程,其中很多是守护进程。ps -aux之后可以看到。里面有一项TTY项,他代表着”终端依赖”。
“比如pts/1”,代表着我们打开的终端窗口,显示?的就是不依赖终端的进程。
3、守护进程简介
守护进程(Daemon)是①运行在后台、②独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件的一种特殊进程。③守护进程常常在系统引导装入时启动,在系统关闭时终止。
Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等
举例:支持FTP的守护进程,syslogd系统日志,cron时间管理守护进程
二、编写简单守护进程
1.Linux系统守护进程的创建流程:
-
1、后台运行
为避免挂起控制终端将守护进程放入后台执行,让进程在后台运行的方法是子进程等待父进程退出
|
if (pid < 0) { perror("fork"); exit(-1); } if (pid > 0) { exit(0); // 父进程直接退出,剩下的全是子进程 } |
-
2、脱离控制终端、登录会话和进程组
子进程使用setsid函数以创建新的会话期目的:脱离控制台
|
// 脱离控制台。 pid = setsid(); |
-
3、改变当前工作目录
调用chdir将当前工作目录设置为/
|
// 将当前进程工作目录设置为根目录 chdir("/"); |
-
4、umask设置为0以取消任何文件权限屏蔽
|
// umask设置为0确保将来进程有最大的文件操作权限 umask(0); |
-
5、关闭所有文件描述符
进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。
|
// 关闭所有文件描述符 // 先要使用sysconf(_SC_OPEN_MAX)获取当前系统中所允许打开的最大文件描述符数目 int cnt = sysconf(_SC_OPEN_MAX); int i = 0; for (i=0; i<cnt; i++) { close(i); } |
-
6、将0、1、2定位到/dev/null
|
///dev/null 这个文件下类似于回收站 存放垃圾的地方 open("/dev/null", O_RDWR); open("/dev/null", O_RDWR); open("/dev/null", O_RDWR); |
2、守护进程创建实例
|
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
void create_daemon(void);
int main(void) { create_daemon(); while (1) { printf("I am running.\n"); sleep(1); } return 0; }
// 函数作用就是把调用该函数的进程变成一个守护进程 void create_daemon(void) { pid_t pid = 0; pid = fork(); /*1、后台运行:子进程等待父进程退出 */ if (pid < 0) { perror("fork"); exit(-1); } if (pid > 0) { exit(0); // 父进程直接退出 } // 执行到这里就是子进程 /*2、脱离控制终端、登录会话和进程组 */ //setsid将当前进程设置为一个新的会话期session,目的就是让当前进程 // 脱离控制台。 pid = setsid(); /*3、改变当前工作目录*/ // 将当前进程工作目录设置为根目录 chdir("/"); /*4、umask设置为0以取消任何文件权限屏蔽*/ // umask设置为0确保将来进程有最大的文件操作权限 umask(0); /*5、关闭所有文件描述符*/ //先要获取当前系统中所允许打开的最大文件描述符数目 int cnt = sysconf(_SC_OPEN_MAX); int i = 0; for (i=0; i<cnt; i++) { close(i); } /*6.将0、1、2定位到/dev/null*/ ///dev/null 这个文件下类似于回收站 存放垃圾的地方 open("/dev/null", O_RDWR); open("/dev/null", O_RDWR); open("/dev/null", O_RDWR);
} |