Detailed summary of the daemon process

concept:

Daemon is a special process that runs in the background. It is independent of the controlling terminal and periodically performs some kind of task or waits for some event to occur. A daemon is a very useful process. Most servers in Linux are implemented as daemons. For example, Internet server inetd, Web server httpd, etc. At the same time, the daemon performs many system tasks. For example, the job planning process crond, the printing process lpd, etc. (The letter d at the end here means Daemon)
Create steps:
① Make the process run in the background
Create child process parent process exit
if((pid = fork())>0)
   exit(0);
else if(pid<0)
{
    perror("fail to fork");
    exit(-1);
}
②Leave the controlling terminal, log in to the session and process group (create a new session)
It is necessary to first introduce the relationship between processes and controlling terminals, login sessions and process groups in Linux: a process belongs to a process group, and the process group ID (GID) is the process ID (PID) of the process group leader. A login session can contain multiple process groups. These process groups share a controlling terminal. This controlling terminal is usually the login terminal from which the process was created. Controlling terminals, login sessions and process groups are usually inherited from the parent process. Our purpose is to get rid of them, to be unaffected by them. The method is to call setsid() on the basis of point 1 to make the process the session leader:
   setsid(); 
Description: The setsid() call fails when the process is the session leader. But the first point already guarantees that the process is not the session leader.
After the setsid() call is successful, the process becomes the new session leader and the new process leader, and is connected with the original login session and progress.
Process group disengages. Due to the exclusivity of the session process to the controlling terminal, the process is simultaneously detached from the controlling terminal.
    
③Prohibit the process from reopening the controlling terminal
Now, the process has become a terminalless session leader. But it can reapply to open a controlling terminal. A process can be prevented from reopening the controlling terminal by making the process no longer the session leader:
    if(pid=fork()) 
exit(0);//End the first child process, the second child process continues (the second child process is no longer the session leader)
④Close all file descriptors
A process inherits open file descriptors from the parent process that created it. If it is not closed, it will waste system resources, cause the file system where the process is located to be unmountable and cause unforeseen errors:
for(i=0;i<=getdtablesize();i++)
close(i);
⑤ Change the current working directory
While the process is active, the file system where its working directory resides cannot be unmounted. It is generally necessary to change the working directory to the root directory. For processes that need to dump the core and write run logs change the working directory to a specific directory such as /tmp:
chdir("/tmp") ;
⑥Reset permission mask
A process inherits the file creation mask from the parent process that created it. It may modify the access bits of files created by the daemon. To prevent this, clear the file creation mask:
umask(0);
⑦Process SIGCHLD signal
It is not necessary to handle the SIGCHLD signal. But for some processes, especially the server process, a child process is often generated to handle the request when the request arrives. If the parent process does not wait for the child process to end, the child process will become a zombie process (zombie) and occupy system resources. If the parent process waits for the child process to end, it will increase the burden on the parent process and affect the concurrent performance of the server process. Under Linux, you can simply set the operation of the SIGCHLD signal to SIG_IGN. 
    signal(SIGCHLD,SIG_IGN); 
This way the kernel doesn't spawn zombie processes when the child process ends. This is different from BSD4, which must explicitly wait for the end of the child process to release the zombie process.
no code no truth
Code description:
init_deamon.c : Create a daemon process according to the above steps
test.c : call the function to create a daemon process, and print the system time to the print_time file in the /tmp directory every second
/*name: init_deamon.c
 *function:Create a daemon
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <signal.h> 
#include <sys/param.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
void init_deamon(void) 
{ 
    int pid; 
    int i;

    /* Handle the SIGCHLD signal. It is not necessary to handle the SIGCHLD signal. But for some processes, especially the server process, a child process is often generated to handle the request when the request arrives. If the parent process does not wait for the child process to end, the child process will become a zombie process (zombie) and occupy system resources.*/
    if(signal(SIGCHLD,SIG_IGN) == SIG_ERR){
        printf("Cant signal in init_daemon.");
        exit(1);
    }
    if(pid=fork()) 
        exit(0);//is the parent process, end the parent process 
    else if(pid< 0){ 
        perror("fail to fork1");
        exit(1);//fork failed, exit
    }
    //Is the first child process, the background continues to execute
    setsid();//The first child process becomes the new session leader and process leader 
    //and separate from the control terminal 
    if(pid=fork()) 
        exit(0);//is the first child process, end the first child process 
    else if(pid< 0) 
        exit(1);//fork failed, exit 
    //is the second child process, continue 
    //The second child process is no longer the session leader 

    for(i=0;i< getdtablesize();++i)//close open file descriptors 
        close(i); 
    chdir("/tmp");//Change working directory to /tmp 
    umask(0);//Reset file to create mask 
    return; 
}

/* name     :test.c
 * function    :Call the init_deamon function to turn the process into a daemon process, and then print the current time to the print_time file in the /tmp directory every second
 * */
#include <stdio.h> 
#include <time.h> 

void init_deamon(void);//Daemon initialization function 
void main() 
{ 
    FILE *fp; 
    time_t t; 
    init_deamon();//Initialized as Daemon 

    while(1)//Report running status to test.log every minute 
    { 
        sleep(1);//sleep for a second 
        if((fp=fopen("print_time","a")) >=0) 
        { 
            t=time(0); 
            fprintf(fp,"The time right now is : %s",asctime(localtime(&t))); 
            fclose(fp); 
        } 
    }
    return;
}

test:




Tags: C++

Posted by DotSPF on Sun, 13 Nov 2022 20:11:32 +0300