Daemon and linux daemon
Because of its long lifetime, it runs tasks independently of the control terminal and session cycle (as described below:
In linux, every interface on which the system communicates with the user is called a terminal. Every process starting from this terminal depends on this terminal, which is called the control terminal of these processes. When the control terminal is closed, the corresponding process is automatically closed. However, the daemon can break through this restriction. It is executed and started to run until the entire system is shut down.
1> the most important feature of the daemon is running in the background.
2> the daemon must be isolated from the environment before running. These environments include unclosed file descriptors, control terminals, sessions and Process Groups, and the masks of files already created in the working directory. These environments are generally inherited by the daemon from the parent process.
3> the startup method of the daemon has its own special characteristics: it can start from the startup script/etc/rc when the linux system starts. d, which can be started by the job planning process crond or by the user terminal (usually shell.
In linux, if you use the daemon method to separate the program from the terminal, is the background process a daemon process? Actually they are not equal!
The most intuitive and important difference is that the daemon process does not have a control terminal, but there are background processes.
1. basically, any program can run in the background, but the daemon process has special requirements, for example, to break away from its parent process and become its own session leader, these should be explicitly written in the code.
2. the daemon becomes the process leader (or session leader) and loses contact with the control terminal (its file descriptor also inherits from the parent process, but stdin, stdout, stderr lost contact with the console ).
3. the background file descriptor is also inherited from the parent process, such as shell, so it can also explicitly output data under the current terminal, but the daemon process itself becomes the process leader, the file description symbol is not associated with the control terminal and is a process that is out of the console.
Summary: The Daemon must be a background process, but the opposite is not true. Daemon, as its name suggests, is mainly used for some long-term operations and monitors its own responsibilities (Listening ports, listening services, etc ). There are many daemon processes in our system.
- Daemon programming rules (Steps ):
Step 1. Run in the background
Concepts:
- Process Group: A collection of one or more processes. A process group is uniquely identified by a process group ID. In addition to the process ID (PID), the process group ID (GID) is also a required attribute of a process. Each process has a leader process whose process ID is the same as the process group ID. And the process group ID will not be affected by the exit of the leader process.
- Session cycle: a set of one or more Process Groups. Generally, a session starts when the user logs on and ends when the user exits. During this period, all processes run by the user belong to this session period.
- Control terminal: in linux, every interface on which the system communicates with the user is called a terminal. Every process starting from this terminal depends on this control terminal.
To avoid suspending the control terminal, place the daemon in the background for execution by calling fork in the process, and then exit the parent process so that the daemon can be executed in the background. In this way, the following two points are implemented:
1. If the daemon is started as a simple shell command, the termination of the parent process will make the shell think that the command has been executed.
2. although the Forbidden City inherits the parent process group ID (pgid), it obtains a new process ID (pid), which ensures that the child process is not the leader process of a process group, this is a prerequisite for the following setsid call!
Control terminal, logon sessions and process groups are generally inherited from the parent process. Our goal is to get rid of them so that they are not affected.
The process calls the setsid function to create a new session.
1 #include<unistd.h>2 pid_t setsid(void);
If the process that calls this function is not the leader of a process group, the function creates a new session and the following three events occur:
1. The process is changed to the new session first process (session leader, which is the process that creates the session ). This process is the only process in the new session. (Get rid of the control of the original session)
2. The process becomes the leader process of a new process group. The new process group ID is the ID of the process that calls the process. (Get rid of the control of the original Process Group)
3. The process has no control terminal. If the process has a control terminal before calling setsid, the connection is also disconnected. (Getting rid of control terminals)
Step 2: Call setsid in the sub-process to create a new session. This will execute the above three things!
Through this step, the new sub-process gets rid of the control of the original Session, the control of the original process group, and the control of the terminal.
Step 3: Prohibit the process from re-opening the control terminal // save, many open-source services do not have fork for the second time
Now, the process has become the no-end session leader.
But it can re-apply to open a control terminal. You can disable the process from re-opening the control terminal by making the process no longer the session leader.
Because the prerequisite for opening a control terminal is that the process must be the session leader! So fork again, end the first sub-process, the second sub-process continues (the second sub-process is no longer the session leader), the second sub-process ID! = Sid (sid is the ID of the first sub-process of the process: sid ). Therefore, you cannot open a new control terminal.
Step 4: change the current directory to the root directory
The current working directory inherited from the parent process may be in a mounted file system. Because the daemon usually exists until the system is started again, if the current working directory of the daemon is in a mounted file system, the file system cannot be detached.
Alternatively, some daemon may change the current working directory to a specified location and perform all their work at this location. For example, the row-based printer offline daemon may change its working directory to their spool directory.
Step 5: Disable all (no longer needed) file descriptors
The new process inherits open files from the parent process (the parent process may be a shell process or another process. These opened files may never be read or written by the daemon, And they consume system resources. In addition, the daemon has lost contact with the terminal, so the characters entered from the terminal cannot reach the daemon. You can use the open_max function or the getrlimit function to determine the maximum file descriptor value, and disable 0 until all descriptors of this value.
Strp 6: reset the file mask
A process inherits the file creation mask from its parent process. It may modify the access bit of the file created by the daemon. That is, you can call umask to set the mask created in file mode to a known (usually 0 ).
Step 7: Process SIGCHLD Signals
It is not necessary to process SIGCHLD signals. However, some processes, especially server processes, usually generate sub-processes to process requests when requests arrive. If the parent process does not wait for the child process to end, the child process will become a zombie process, occupying 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. In Linux, you can set the SIGCHLD signal operation to SIG_IGN.
signal(SIGCHLD,SIG_IGN);
In this way, the kernel will not generate zombie processes when the child process ends. This is different from BSD4. In BSD4, you must explicitly wait for the child process to end before releasing the zombie process.
1 # include <stdio. h> 2 # include <stdlib. h> 3 # include <unistd. h> 4 # include <sys/stat. h> 5 void Daemon () 6 {7 const int MAXFD = 64; 8 int I = 0; 9 if (fork ()! = 0) // The parent process exits 10 exit (0); 11 setsid (); // becomes the new process group leader and new session leader, exit Control Terminal 12 chdir ("/"); // set the working directory to the root directory 13 umask (0); // reset the file access permission mask 14 for (; I <MAXFD; I ++) // close all files inherited from the parent process as much as possible 15 close (I); 16} 17 int main () 18 {19 Daemon (); // become daemon 20 while (1) {21 sleep (1); 22} 23 return 0; 24}
(To be completed)