Daemon production

1. What is a daemon process?

        The daemon process, also known as the Daemon process, is a background service process in Linux. It is a long-lived process that is usually independent of the controlling terminal and periodically performs certain tasks or waits for processing of certain events. Daemons are often started when the system is booted and terminated when the system is shut down. There are many daemon processes in Linux systems, and most services are implemented using daemon processes. In Linux, the interface through which each system communicates with users is called a terminal. Every process that starts running from this terminal will be attached to this terminal. This terminal is called the control terminal of these processes. When the control terminal is closed, the corresponding All processes will be automatically shut down. The daemon process can break through this limitation. It starts running from the moment it is executed and does not exit until the entire system is shut down. If you want a process not to be affected by user or terminal or other changes, you must turn this process into 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.

Guess you like

Origin blog.csdn.net/apple_71040140/article/details/132483357