A daemon is a special process that runs in the background. It is independent of the control terminal and periodically performs some sort of task or waits to handle certain occurrences. Daemons are a useful process, and most Linux servers are implemented with daemons.
Steps to create the daemon:
1. Make the process run in the background (create child process, parent process exits)
if ((Pid=fork ()) >0)
Exit (0);
else if (pid<0)
{
Perror ("fail to fork");
Exit (-1);
}
2. Out of control terminal, logon session and process group (create new session)
Process belongs to a process group, process group number process leader's process number. A session can contain multiple process groups that share a control terminal, which is typically the logon terminal for the creation process. Control terminals, sessions, and process groups are usually inherited from the parent process. Our aim is to get rid of them so that they are not affected by them. The method is based on the 1th, call Setsid () to make the process a conversation leader:
Setsid ();
Description: The Setsid () call failed when the process was the session leader. But the 1th has ensured that the process is not a conversation leader. After the Setsid () call succeeds, the process becomes the new session leader and the new process leader, and is detached from the original logon session and process group. Because the session process is exclusive to the process, the process is detached from the control terminal at the same time.
3. Disable process re-opening control terminal
Now the process has become a session leader without terminal, but it can reapply to open a control terminal. You can disable a process from opening the control terminal by not becoming a session leader:
if (Pid=fork ())
Exit (0); End first child process, second child process is not session leader
4. Close all file descriptors
The process inherits the open file descriptor from the parent process that created it. If you do not close, you will waste system resources and unexpected errors.
Close (0);
Close (1);
Close (2);
5. Change the current working directory:
The file system in which the working directory resides cannot be unloaded while the process is active. It is generally necessary to change the working directory to the root directory.
ChDir ("\");
6. Reset the permission mask:
The process inherits the file creation mask from the parent process that created it. It may modify the access bit of the file created by the daemon. To prevent this, we want to clear the file creation mask:
Umask (0);
7. Process the SIGCHLD signal:
Processing SIGCHLD signals is not a must. However, for some processes, in particular, server processes often generate child processes to process requests when requests arrive. If the parent process does not wait for the child process to end, the child process becomes a zombie process, which consumes system resources. If the parent process waits for the end of the child process, it increases the burden on the parent process and affects the concurrency performance of the server process.
Signal (sigchld,sig_ign);
Let's look at the specific code: (simulation to implement a simple daemon)
MY_DAEMON.C file
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void My_daemon ()
{
Umask (0);
pid_t id1=fork ();
if (id1<0)
{
Perror ("fork");
Exit (1);
}
if (id1>0)
{
Exit (0);
}
Setsid ();
pid_t id2=fork ();
if (id2<0)
{
Perror ("fork");
Exit (1);
}
if (id2>0)
{
Exit (0);
}
Signal (sigchld,sig_ign);
ChDir ("/");
Close (0);
Close (1);
Close (2);
}
int main ()
{
My_daemon ();
while (1)
{}
return 0;
}
The results of the operation result are as follows:
650) this.width=650; "title=" Si@8udqw}wb18d0[902xs4p.png "src=" http://s5.51cto.com/wyfs02/M00/7F/F0/ Wkiom1cx3b3dsoxgaaayfwxveww247.png "alt=" Wkiom1cx3b3dsoxgaaayfwxveww247.png "/>
We can see that there is a process with process number 1, which proves that we have generated the daemon.
The following is a relatively complete daemon, which outputs time information to daemon.log files at a certain time:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
void My_daemon ()
{
Umask (0);
pid_t id1=fork ();
if (id1<0)
{
Perror ("fork");
Exit (1);
}
if (id1>0)
{
Exit (0);
}
Setsid ();
pid_t id2=fork ();
if (id2<0)
{
Perror ("fork");
Exit (1);
}
if (id2>0)
{
Exit (0);
}
Signal (sigchld,sig_ign);
ChDir ("/");
Close (0);
Close (1);
Close (2);
}
int main ()
{
file* FP;
time_t T;
Fp=fopen ("Daemon.log", "a");
Char *buf= "Hello bit";
My_daemon ();
while (1)
while (1)
{
Sleep (1);
T=time (0);
fprintf (FP, "This is a daemon:%s", Asctime (LocalTime (&t)));
}
Fclose (FP);
return 0;
}
Methods and procedures for creating daemons