1. What is a daemon process?
2. View commonly used system daemons
父进程ID : PPID
进程ID : PID
进程组ID : PGID
会话期ID : SID
终端ID : TTY
终端进程组ID : TPGID
状态 : STAT
用户 : UID
运行时间 : TIME
指令: COMMAND
3. Daemon process production process
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include<syslog.h>
void deamon_init(void);
int main(){
deamon_init();
openlog("opening",LOG_PID,LOG_DAEMON);
int fd = open("1.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
if(fd<0){
syslog(LOG_ERR,"open error");
exit(-1);
}
char buf[50]="hello,this is deamo\n";
while(1){
sleep(3);
write(fd,buf,strlen(buf));
syslog(LOG_INFO,"%s",buf);
}
closelog();
return 0;
}
void deamon_init(void){
if(fork()!=0)
exit(0);
if(setsid()<0){
perror("setsid:");
exit(-1);
}
if(fork()!=0)
exit(0);
int i;
for(i = 0;i <= sysconf(_SC_OPEN_MAX);i++)
close(i);
chdir("/home/pm");
umask(0);
int fd = open("/dev/null",O_RDWR);
dup(0);
dup(0);
}
4. Preparation of daemon process
step:
1. Create a child process and kill the parent process:
Preparing for making a terminal process: The group leader process cannot become a terminal
//创建子进程,exit结束父进程,fork返回值是父进程pid且大于0
if(fork()!=0)
exit(0);
2. Set the current child process as a terminal:
In order to get rid of the control relationship of the original terminal
//设置子进程为终端,返回值为0没有参数
if(setsid()<0){
perror("setsid");
exit(-1);
}
3. Create a child process and kill the parent process:
It has completely become the prototype of a daemon process that cannot be affected by the concepts of process management and control terminals.
再次创建子进程杀死父进程,让新创建的子进程完全成为摆脱终端关系的进程
if(fork()!=0)
exit(0);
//此时,守护进程雏形已完成,剩下的操作,子进程2(守护进程雏形)做
4. Close all file descriptors:
Prepare for point seven
int i;
for(i=0;i<=sysconf(_SC_OPEN_MAX);i++)//for里面写表达式并不好:容易出现bug
close(i); //不要再for里写任何表达式,引以为戒
5. Change the execution directory:
To prevent the daemon from affecting the deletion and move operations of the source directory
//执行目录更改到根目录下,运行时记得添加sudo
chdir("/");
6. Modify the mask:
In order to prevent daemon process operations from being affected by permissions
umask(0);
7. Redirect standard input, standard output, and standard error output to device NULL
Standard input, output, and error output initially have corresponding trigger devices.
//7>将标准输入、标准输出、标准错误输出重定向到设备null
int fd=open("/dev/null",O_RDWR);
dup(0);
dup(0);
API学习:
2>设置当前子进程为一个终端
setsid
#include <sys/types.h>
#include <unistd.h>
pid_t setsid(void);
功能:
让执行该函数的进程,变成终端
参数:
无
返回值:
成功返回0
失败返回-1,并设置错误码
4>关闭所有文件描述符
sysconf
#include <unistd.h>
long sysconf(int name);
功能:
找寻name选项的最大值
参数:
name:_SC_OPEN_MAX -->找寻文件描述符的最大值
返回值:
成功找到选项的最大值
失败返回-1,并设置错误码
5>更改执行目录
chdir
#include <unistd.h>
int chdir(const char *path);
功能:
改变目录
参数:
path:需要修改到的目录
返回值:
成功返回0
失败返回-1,并设置错误码
6>修改掩码: 两种方式
1>命令修改 --->适用于终端
2>函数修改 --->适用于进程 ---!
umask --》和命令同名
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
功能:
修改某个进程当中操作的掩码
参数:
mask:掩码值
返回值:
成功返回掩码值
7>文件描述符重定向(复制)
dup
#include <unistd.h>
int dup(int oldfd);
功能:
以oldfd为模板,复制出一个新fd
新fd所有的参数 都 继承 oldfd
操作oldfd = 操作 新的fd
参数;
oldfd:旧文件描述符
返回值:
成功创建newfd并返回 newfd
失败返回-1,并设置错误码
5. Daemon process logging
Why log:
The daemon process has no input and output, and does not report errors. We cannot conduct relatively simple tracking of it, nor can we know what operations it does behind our backs. So we: use the file log system to save the operation information of the daemon process
file logging system
ubuntu的文件系统是:Ext4
Ext4:两种系统:
1>文件日志系统 --->保留下来
2>时间回溯系统 ---->快照
系统日志:
1>打开日志
openlog
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
功能:
打开日志
参数:
ident:标签:char * 随意
option:选项
LOG_PID :进程信息
facility:
LOG_DAEMON :守护进程
2>写日志
syslog
#include <syslog.h>
void syslog(int priority, const char *format, ...);
功能:
编写日志
参数:
priority:优先级(报文)
LOG_ERR:出错
LOG_WARNING:警告
LOG_INFO:正常
format:类似printf
3>关闭日志
closelog
#include <syslog.h>
void closelog(void);
功能:
关闭日志
4>命令:查看日志
vi /var/log/syslog
6. Check the daemon process
ps -ajx When TPGID displays -1, it indicates a daemon process
Run the program:
After execution, it displays:
The daemon will not be closed when the terminal is closed, but will run in the background:
There is still a display in the background
Restarting the virtual machine will kill the daemon we wrote:
Appears in the home directory: the writer running in the daemon process.
At this point the daemon process ends.