Reprinted from http://blog.csdn.net/tigerjb/article/details/6007073
We learned how to create a process through the fork () function and vfork () function. Now let's continue to learn two special processes: orphan process and daemon process.
1. Orphan Process
1. What is an orphan process?
If the parent process of a child process ends before the child process, the child process becomes an orphan process, which is adopted by the INIT process and becomes the child process of the init process.
2. How can we turn a process into an orphan process?
We can first create a process and then kill its parent process, then it becomes an orphan process.
PID = fork ();
If (pid> 0 ){
Exit (0 );
}
3. Function instance:
1 # include <stdio. h>
2 # include <unistd. h>
3 # include <sys/types. h>
4 # include <stdlib. h>
5
6 int main ()
7 {
8 pid_t PID;
9 pid = fork ();
10 if (! PID ){
11 while (1 ){
12 printf ("A background process, PID: % d/N, parentid: % d/N", getpid (), getppid ());
13 sleep (3 );
14
15}
16}
17 else if (pid> 0 ){
18 printf ("I am parent process, my PID is % d/N", getpid ());
19 exit (0 );
20}
21 else {
22 printf ("process creation failed! /N ");
23}
24 return 0;
25
26}
Program running result
I am parent process, my PID is 2026
A background process, PID: 2027
, Parentid: 2026
Think @ Ubuntu :~ /Work/process_thread/fork2 $ A background process, PID: 2027
, Parentid: 1
A background process, PID: 2027
, Parentid: 1
A background process, PID: 2027
, Parentid: 1
A background process, PID: 2027
, Parentid: 1
A background process, PID: 2027
, Parentid: 1
A background process, PID: 2027
, Parentid: 1
Tiger-John note:
With the above method, you can turn a process into an orphan process. When you want to end an orphan process, you can only enter the command: Kill 2027 (kill orphan process number) on the terminal to end its operation.
2 daemon process
1. What is a daemon?
(Daemon) is a process that runs in the background and does not control the connection between the terminal and it. It is independent of the control terminal and usually periodically executes a task.
Tiger-John note:
So why should the daemon process run out of the background?
The daemon is separated from the terminal to prevent information generated by the process from being displayed on any terminal and the process is not interrupted by any terminal information.
2. Why do you want to introduce a daemon:
In Linux, every system interface that communicates with users is called a terminal. Every process starting from this terminal is attached to 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 does not exit until it is executed. To prevent a process from being affected by user, terminal, or other changes, you must turn the process into a daemon.
3. Daemon features
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, working directories, and file creation masks. These environments are generally inherited by the daemon from the parent process (especially the shell) that executes the daemon.
3> at last, the daemon startup method has its own special features. It can be started from the startup script/etc/rc. d when the Linux system is started. It can be started by the job planning process crond and executed by the user terminal (usually shell.
4. daemon can be started in the following ways:
A. It can be started from the startup script/etc/rc. d When Linux is started.
B. It can be started by the job planning process crond;
C. It can also be executed by the user terminal (usually shell.
Summary of tiger-JOHN:
A daemon is a background service process in Linux. It is a long-lived process, usually independent of the control terminal and periodically executes a task or waits to process some events. Daemon is often started during system boot and ended when the system is shut down. In Linux, there are many daemon processes. Most services are implemented through daemon. At the same time, daemon can complete many system tasks, for example, job planning process crond and printing process lqd (the ending letter D indicates Daemon ).
5. How to Write the daemon process?
Step 1: create a child process and exit the parent process
1> because the daemon is out of the control terminal, after completing the first step, it will create the illusion that a program has been run on the shell terminal. All subsequent work is completed in the sub-process, and the user can execute other commands in the shell terminal, thus achieving the separation from the control terminal in form.
2> in Linux, when a parent process exits before the child process, the child process becomes an orphan process, and every time the system discovers an orphan process, it will be adopted by process 1 (init.
The method is to call fork to generate a sub-process and then exit the parent process.
PID = fork ();
If (0 = PID)
Exit (0); // if it is a parent process, it ends the parent process and the child process ends.
Step 2: Create a session in the sub-process:
This step is the most important step to create a daemon. Use the system function setsid.
Tiger-John added:
Several Concepts
A. 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 group has a leader process. The process ID of the leader process is equal to the Process Group ID. The process group ID will not be affected by the exit of the leader process.
B. session cycle: a set of one or more Process Groups. Generally, a session starts to log on to the user and ends when the user exits. the processes used by the user during this period belong to this session period.
C. A logon session can contain multiple Process Groups. These process groups share a control terminal. This control terminal is usually the login terminal that creates a process.
Tiger-John note:
Why are they involved?
Because of the control terminal, login sessions and process groups are generally inherited from the parent process. We just need to get rid of them so that they will not be affected.
So how to implement it? At this time, we can call the setsid () function based on the first step.
1> the setsid function is used to create a new session and act as the group leader. Calling setsid has the following three functions:
Remove the process from the control of the original session
Remove the process from the control of the original Process Group
Remove the process from the control of the original Process Group
Remove the process from the control of the original control terminal
2>. Why call the setsid function when creating a daemon?
The fork function is called to create a child process in the first step of daemon creation, and then the parent process is exited. When the fork function is called, the child process completely copies the session period, process group, and control terminal of the parent process. Although the parent process has exited, the session period, process group, the control terminal is not changed. Therefore, it is not truly independent. The setsid function can make the process completely independent and thus get rid of the control of other processes.
Tiger-John note:
A. When the process group is the session leader, setsid () fails to be called. However, the first step ensures that the process is not the session leader.
B. After setsid () is called successfully, the process becomes a new session leader and a new process leader, and is detached from the original logon session and process group. Because the session process is dedicated to the control terminal, the process is separated from the control terminal at the same time.
C. At this point, we need to disable the process from re-opening the control terminal.
Although the process has become a non-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:
So how to implement it?
We can create a sub-process again and exit the parent process to ensure that the process is not the process leader and the process cannot open a new terminal.
PID = fork ();
Exit (0 );
Step 3: change the current directory to the root directory
1> the child process created using fork inherits the current working directory of the parent process. The file system of the current directory cannot be uninstalled during the process, which may cause a lot of inconvenience in future use. Therefore, we generally make "/" the current working directory of the daemon to avoid the above problems. If you have special requirements, you can change the current working directory to another path.
2> the common function for changing the working directory is chdir ().
Step 4: reset the File Permission mask
1> the File Permission mask is used to block the corresponding bits in the file permission. The Subprocess created by using the fork function inherits the File Permission mask of the parent process, which causes a lot of trouble for the subprocess to use files. Therefore, setting the File Permission mask to 0 can greatly improve the flexibility of the daemon process.
2> the File Permission mask function is umask. The common method is umask (0 ).
Step 5: Disable the file descriptor
1> because the child process created using the fork function will inherit some opened files from the parent process. These opened files may never be read or written by the daemon, But they consume the same system resources and may cause the file system to be unable to be detached.
2> after step 2, the daemon has lost contact with the control terminal. Therefore, the characters entered from the terminal cannot reach the daemon, and the characters output by conventional methods (such as printf) in the daemon cannot be displayed on the terminal. Therefore, the three files whose file descriptors are 0, 1, and 2 (input, output, and error) have lost meaning and should be disabled.
3> function instances:
For (I = 0; I <maxfile; I ++)
Close (I );
Step 6: Process sigchld Signals
1> processing sigchld signals is not necessary. 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 service process.
2> function implementation:
Signal (sigchld, sig_ign );
In this way, the kernel will not generate zombie processes when the child process ends.
6. Specific function implementation:
Writing a daemon consists of the main program test. C and the initialization program init. C.
The init_daemon function in the initialization program is responsible for generating the daemon process. You can use the init_daemon function to generate your own daemon.
Daemon. c
1 # include <stdio. h>
2 # include <signal. h>
3 # include <sys/Param. h>
4 # include <sys/types. h>
5 # include <sys/STAT. h>
6 # include <stdlib. h>
7
8 int init_daemon (void)
9 {
10 pid_t PID;
11 int I;
12
13 pid = fork ();
14 if (pid> 0) {// The first step ends the parent process, making the child process a background
15 exit (0 );
16}
17 else if (PID <0 ){
18 return-1;
19}
20/* Create a New Process Group in the second step. In this new process group, the sub-process becomes the first process in the Process Group to remove the process from the terminal used */
21 setsid ();
22/* Create a new sub-process and exit the parent process to ensure that the process is not the process leader. At the same time, the process cannot open a new terminal */
23 pid = fork ();
24 if (pid> 0 ){
25 exit (0 );
26}
27 else if (PID <0 ){
28 return-1;
29}
30 // Step 3: disable unnecessary file descriptors inherited from the parent process
31 For (I = 0; I <nofile; close (I ++ ));
32 // Step 4: change the working directory so that the process does not contact any File System
33 chdir ("/");
34 // Step 5: Set the blocked word to 0
35 umask (0 );
36 // Step 6: Ignore the sigchld Signal
37 signal (sigchld, sig_ign );
38 return 0;
39}
Test. c
1 # include <stdio. h>
2 # include <time. h>
3 # include <syslog. h>
4 extern int init_daemon (void );
5
6 int main ()
7 {
8 time_t now;
9 init_daemon (); // initialize daemon
10 syslog (log_user | log_info, "test daemon! /N ");
11 while (1 ){
12 sleep (8); // sleep for one minute
13 Time (& now );
14 syslog (log_user | log_info, "system time:/T % S/T/N", ctime (& now ));
15}
16}
17
The program has been debugged in Ubuntu 2. 6.
Think @ Ubuntu:/etc $ gcc-g-o Test daemon. C test. c
Think @ Ubuntu:/etc $./test
After compilation, you can use PS-Ef to view the process status,
Think @ Ubuntu:/etc $ PS-ef
Uid pid ppid C stime tty time cmd
Think 2995 1 0? 00:00:00./test
From this, we can see that the process has the features used by the daemon process.
View System Logs
Think @ Ubuntu :~ $ CAT/var/log/syslog
Nov 13 11:05:37 Ubuntu test: test the daemon!
Nov 13 11:05:45 Ubuntu test: System Time: # 011sat Nov 13 11:05:45 2010 #012 #011 #011
Nov 13 11:05:53 Ubuntu test: System Time: # 011sat Nov 13 11:05:53 2010 #012 #011 #011
Nov 13 11:06:01 Ubuntu test: System Time: # 011sat Nov 13 11:06:01 2010 #012 #011 #011
Nov 13 11:06:09 Ubuntu test: System Time: # 011sat Nov 13 11:06:09 2010 #012 #011 #011
Nov 13 11:06:17 Ubuntu test: System Time: # 011sat Nov 13 11:06:17 2010 #012 #011 #011
Nov 13 11:06:25 Ubuntu test: System Time: # 011sat Nov 13 11:06:25 2010 #012 #011