I. Concepts of terminals
In a UNIX system, a user logs on to the system through a terminal and obtains a shell process. The terminal becomes the controlling terminal of the shell process. The control terminal is the information stored in the PCB, we know that fork will copy information in the PCB, so the control terminal of other processes started by the shell process is also the terminal. By default (no redirection), the standard input, standard output, and standard error output of each process point to the control terminal. The process reads from the standard input, that is, the user's keyboard input, the process writes to the standard output or standard error output, that is, the output to the display. Enter some special control keys on the control terminal to send signals to the foreground process. For example, Ctrl-c Indicates SIGINT and Ctrl-\ indicates sigquit.
Each process can access its control terminal through a special device file/dev/tty. In fact, each terminal device corresponds to a different device file./dev/tty provides a common interface, A process can access its control terminal either through/dev/tty or through the device file corresponding to the terminal device. The ttyname function can be used to identify the corresponding file name by the file descriptor. The file descriptor must point to a terminal device rather than any file. The tty command on Linux can also view the current terminal.
For example, if we open a terminal in the graphic interface, it may be/dev/pts/0, and the second may be/dev/pts/1... (Network Terminal)
Switching to the character interface may be/dev/tty1... (virtual terminal)
Ii. Job Control
In fact, shell is not controlled by processes, but by jobs or process groups ). A foreground job can be composed of multiple processes, and a background job can also be composed of multiple processes. Shell can run a foreground job and any number of background jobs at the same time, this is called jobcontrol ). For example, run the following command to start five processes (this example is from apue ):
$ Proc1 | proc2 &
$ Proc3 | proc4 | proc5
Proc1 and proc2 belong to the same background process group, proc3, proc4, and proc5 belong to the same foreground process group, and the shell process itself belongs to a separate process group. The control terminals of these process groups are the same. They belong to the same session. A session is related to a control terminal. When you enter a special control key (for example, Ctrl-C) on the control terminal, the kernel sends a signal (for example, SIGINT) to all processes in the foreground process group. Shows the relationship between processes, Process Groups, and sessions.
In the preceding example, proc3, proc4, and proc5 are put in the same frontend process group by shell. One of the processes is the leader of the Process Group, and shell calls wait to wait for them to finish running. Once all of them are finished, shell calls the tcsetpgrp function and mentions it to the foreground to continue to accept the command. However, if a process in proc3, proc4, and proc5 forks out sub-processes, the sub-processes also belong to the same process group, but the shell does not know the existence of the sub-process, it will not call wait to wait for it to end. In other words, proc3 | proc4
| Proc5 is a shell job, but this sub-process is not. This is a conceptual difference between a job and a process group. Once the job finishes running, shell will introduce itself to the foreground. If the original foreground process group still exists (if the child process has not been terminated), it will automatically become a background process, taken over by the INIT process.
3. Daemon
A daemon is a process controlled by an uncontrolled end in the background. Generally, the daemon runs automatically when the system starts. Closing or canceling a terminal window does not affect the running of the daemon, only kill is allowed. The daemon name usually ends with D, such as sshd, Xinetd, and crond.
We use the PS axj command to view the processes in the system. What in the tpgid (foreground Process Group ID) Column says-1 is a process with no control terminal, or is the TTY column? That is, the daemon process.
4. Create a daemon
Call fork () to create a new process. It will be a future daemon process.
Call exit in the parent process to ensure that the child process is not the process group leader
Call setsid to create a new session
Change the current directory to the root directory.
Redirects standard input, standard output, and standard errors to/dev/null
The result of successfully calling the setsid function is:
Create a new session. The current process becomes the session leader. The current process ID is the session ID.
Create a new process group. The current process becomes the leader of the Process Group. the ID of the current process is the ID of the Process Group.
If the current process originally has a control terminal, it will lose the control terminal and become a process without control terminals.
Example program:
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
|
/*************************************** ********************************** > File name: Process _. c > Author: Simba > Mail: dameng34@163.com > Created time: sat 23 Feb 2013 02:34:02 pm CST **************************************** ********************************/ # Include <sys/types. h> # Include <sys/STAT. h> # Include <unistd. h> # Include <fcntl. h> # Include <stdio. h> # Include <stdlib. h> # Include <errno. h> # Include <string. h># Define err_exit (m )\ Do {\ Perror (m );\ Exit (exit_failure );\ } While (0) Int setup_daemon (INT, INT ); /* The daemon has been running in the background and has no control terminal */ Int main (INT argc, char * argv []) { // Daemon (0, 0) Setup_daemon (0, 0 ); Printf ("test... \ n"); // No output For (;;); Return 0; } Int setup_daemon (INT nochdir, int noclose) { Pid_t PID; PID = fork (); If (pid =-1) Err_exit ("fork error "); If (pid> 0) Exit (exit_success ); /* The process that calls setsid cannot be the process group leader, so the parent process is exited after fork */ Setsid (); // a new session is generated after the sub-process is called. If (nochdir = 0) Chdir ("/"); // change the current directory to the root directory If (noclose = 0) { Int I; For (I = 0; I <3; ++ I) Close (I ); Open ("/dev/null", o_rdwr); // redirects standard input and standard output to/dev/null. DUP (0 ); DUP (0 ); } Return 0; } |
Run the program PS axj:
Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/process $./daemon
Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/process $ PS axj
Ppid PID pgid Sid tty tpgid stat uid Time Command
........................................ ........................................ ...........................................
1 7678 7678 7678? -1 Rs 1000./daemon
It can be seen that the ID of the daemon is also the ID of the Process Group and the session ID. In addition, there is no foreground process group in this session.
5. Use the daemon function to implement the daemon process
Function: Creates a daemon.
Prototype: int daemon (INT nochdir, int noclose );
Parameters:
Nochdir: = 0 change the current directory to "/"
Noclose: = 0 redirects standard input, standard output, and standard error to "/dev/null"
Reference: Linux C Programming one-stop learning and apue