守护进程(Daemon)
来源:互联网 发布:充值系统源码 编辑:程序博客网 时间:2024/05/22 06:52
Hello,地球人们,Val今天来给大家分享一下关于守护进程的一些知识^_^
1. 守护进程是什么?
守护进程也叫精灵进程(Daemon),是运行在后台的一种特殊进程。她独立于终端并且周期性地执行某种人物或者等待某些发生的事件。
Linux的大多数服务器就是用守护进程实现的,例如:Internet服务器 inetd,Web服务器httped等。同时守护进程完成许多系统任务。如,作业规划进程crond等。
特点:不受用户登录注销等动作的影响。
2. 创建守护进程
创建守护进程最关键的一步是调用setsid函数创建一个新的会话(session),并成为话首进程(session leader)。
函数 pid_t setsid(void);
该函数创建成功时返回新创建的Session的id(当前进程的id),出错返回-1。fork()创建进程,然后让父进程退出exit,在子进程里调用setsid()。
成功调用该函数的结果是:
(1)创建一个新的会话(Session ),当前进程称为会话的话首进程,当前进程的id就是Session的id。
(2)创建一个新的进程组,当前进程成为进程组的组长进程,当前进程id就是进程组的id。
(3)如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程。失去控制终端指,原来的控制终端仍是打开的,仍然可以读写,但只是一个普通的打开文件而不是控制终端了。
- 代码如何编写,关键步骤是哪些?
创建守护进程
*1.调用umask将文件模式创建屏蔽字设置为0
*2.调用fork,父进程exit。(如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止使得shell认为该命令执行完毕;保证子进程不是一个进程组的组长进程)。
*3.调用setsid创建一个新会话。
setsid使调用进程成为新会话的首进程;
调用进程成为一个进程组的组长进程;
调用进程没有控制终端(再次fork一次,保证daemon进程之后不会打开tty设备)。
*4.当前工作目录改为根目录。
*5.关闭不需要的文件描述符。
*6.忽略SIGCHLD信号。
4.写一个daemon函数创建守护进程
代码如下:
#include <stdio.h>#include <signal.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <sys/stat.h>void creat_daemon(void) { int i; int fd0; pid_t pid; struct sigaction sa; umask(0); //设置文件掩码为0 if( (pid = fork()) < 0 ) { } else if (pid != 0){ exit(0); //终止父进程 } setsid(); //设置新会话 sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if( sigaction(SIGCHLD, &sa, NULL ) < 0 ) { // 注册子进程退出忽略信号 return; } if( (pid = fork())<0) { //再次fork,终止父进程,保持子进程不是话⾸进程,从而保证后续不会在和其他终端关联 printf("fork error!\n"); return; } else if( pid != 0) { exit(0); } if( chdir("/") < 0 ) {//更改工作目录到根 printf("child dir error\n"); return; } close(0); fd0 = open("/dev/null", O_RDWR);// 关闭标准输入,重定向所有标 准(输入输出错误)到/dev/null dup2(fd0, 1); dup2(fd0, 2); } int main() { creat_daemon(); while(1) { sleep(1); } }
运行结果如下图:(请原谅我图片里的错误的单词,其实应该是daemon我却写错了really,really sorry)
守护进程自成会话,自成进程组。
4.setsid()的作用是什么?
setsid()使得子进程成为会话组长(sid=pid),也是进程组组长(pgid==pid),并且脱离了原来的控制终端。所以,控制终端无论怎么操作,新的进程正常情况下不会收到它发来的信号。
5.umask(0)的作用:
子进程从父进程那里继承了一些东西,可能未把权限继承下来,所以要赋予它更高的权限,便于子进程操作。
6.chdir(“/”)作用:
进程活动时,其工作目录所在的文件系统不能卸下,一般需要将工作目录改变到根目录。
7.为什么创建守护进程时有人fork两次?
第一次fork为后面的setsid服务,setsid的调用者不能是进程组组长,而第一次调用的时候父进程是进程组组长。第二次调用后,把前面一次fork出来的子进程退出,这样第二次fork出来的子进程就和他们脱离了关系。其实第二次fork也不是必须的,也可以只fork一次,然后让父进程退出,子进程调用setsid,上面的代码例子就是后者。
- 守护进程(Daemon)
- 守护进程(Daemon)
- 守护进程(Daemon)
- 守护进程(daemon)
- 守护进程(Daemon)
- 守护进程(daemon)
- 守护进程(daemon)
- 守护进程(Daemon)
- 守护进程(daemon)
- 守护进程(daemon) .
- 守护进程(daemon)
- 守护进程(daemon)
- 守护进程(daemon)
- 守护进程(daemon)
- 守护进程(Daemon)
- 守护进程(daemon)介绍
- 守护进程(daemon)介绍
- Linux Daemon(守护进程)
- Spring Boot系列教程六:日志输出配置log4j2
- 使用 Ambari 安装 Hadoop 集群
- 2016最新CocoaPods安装和错误解决
- des 3des aes ides rsa 对称加密算法
- MPEG4与.mp4
- 守护进程(Daemon)
- vim如何删除文件中所有东西
- SimpleDateFormat.format的简单使用小结
- Fragment回退栈管理
- 关于 bash:$'\r': command not found 的问题
- 个人博客的搭建
- ViewStub
- SSD5 数据结构 Course Design Exercise 3 解析
- 那么来一波模板吧=。=