APUE 2, APUE
Process group)
A process group is a collection of one or more processes. They are usually associated with the same job (which can receive signals from the same terminal. Each Process Group has a unique Process Group Id. You can use getpgrp or getpgid to obtain the Process Group Id of a Process:
1 # include <unistd. h> 2 3/* 4 return the process group Id of the calling process 5 */6 pid_t getpgrp (void); 7 8/* 9 if the pid is 0, same as getpgrp 10 */11 pid_t getpgid (pid_t pid );
Each process group can have a process group leader whose process Id is the same as the process group id. No matter whether the process group leader is terminated or not, the Process Group will not disappear as long as there are unterminated processes in the process group. The process group leader does not exist in the process group after it is terminated. It does not automatically select a new process group leader. See: Must a process group have a running leader process?
You can use the setpgid function to set the process group Id:
1 # include <unistd. h> 2 3/* 4 set the Id of the pid process group to pgid5 */6 int setpgid (pid_t pid, pid_t pgid );
The calling Process can only set the Process Group Id of itself and its sub-processes. If the sub-Process calls the exec class function, the Process Group Id of the sub-Process cannot be changed. In job-control shells, this method is often used for fork to call the later parent Process to set the Process Group Id of the child Process, or the child Process to set its own Process Group Id. Of course, after fork is called, the child Process will inherit the Process Group Id of the parent Process, the purpose of setpgid after fork is to ensure the Process Group Id of the sub-Process and avoid exceptions caused by the concurrency status (this place is not quite understandable and did not build the final state environment as imagined by the author ).
Session)
A session is a set of one or more Process Groups.
The session structure shown in can be represented by pipeline in shell:
proc1 | proc2 &proc3 | proc4 | proc5
In the above example, the process group where login shell is located and the process group where proc1 and proc2 are located are the background process group, and the process group where proc3, proc4, and proc5 are located is the foreground process group. One session can have only one foreground process group and one or more background process groups. We will introduce the foreground and background process groups later.
A process can use setsid to create a new session.
1 # include <unistd. h> 2 3/* 4 success. The process group ID is returned; otherwise,-15 */6 pid_t setsid (void) is returned );
The setsid function returns the Process Group Id of the calling Process and the Process Id of the calling Process, because the session leader is always the Process Group leader. In fact, there is no "Session Id" like Process Id or Process Group Id in UNIX, and some are only "Session leader ". We can consider the Process Group Id or Process Id of the session leader as the session Id of the Session.
When setsid is called, three things will happen:
- Call the process to become the session leader of the new session (A session leader is the process that creates a session ). This process is the only process in the new session.
- Call the process to become the leader of the new process group. The Process Group ID of the new Process Group is the Process ID of the called Process.
- There will be no control terminals for the calling process. If the calling process has a control terminal before calling setsid, it will disconnect the control terminal after calling setsid.
The process group leader cannot call setrsid. If the caller is a process group leader, setsid returns an error (probably because a process cannot be a leader of two process groups ?). To ensure that the caller of setsid is not a process group Id, many implementations call fork and terminate the parent process so that the sub-process can continue to run. We can ensure that the child process is not the leader of any process group at this time. Because the child Process inherits the Process Group of the parent Process, and the Process Id of the child Process is newly generated, the Process Id of the child Process cannot be the same as the Process Group Id inherited by the child Process. You can use the getsid function to obtain the Process Group Id of the session leader:
1 # include <unistd. h> 2 3/* 4 get the Process Group ID6 */7 pid_t getsid (pid_t pid) of the session leader5 where the pid is located );
Controlling terminal)
Session and process group have the following features:
- A session can have a control terminal (or none of them ). It is usually the terminal device or Pseudo Terminal when we log on.
- The session leader that creates a connection with the control terminal is called the control Process ).
- A process group in a session can be divided into one foreground process group and one or more background process groups.
- If a session has a control terminal, it has a forward process group. Other Process Groups in this session are background process groups.
- Whenever we press the terminal's stop key (usually DELETE or Crtl-C), a stop signal is sent to all processes in the foreground process group.
- Whenever we press the terminal's return key (usually Crtl-Backslash), an exit signal is sent to all processes in the foreground process group.
- If the terminal interface detects that the network is disconnected, the hang-up signal is sent to the control process, that is, the session leader.
Describes these features:
Generally, we do not need to care about the control terminal. It is automatically created when we log on. Some programs need to communicate with the control terminal, whether using standard output or standard input redirection. The program reads/dev/tty files when communicating with the control terminal. This special file is synonymous with control terminals in the kernel. If the program has no control terminal, opening the/dev/tty file will fail.
You can use the tcgetpgrp function to obtain the foreground Process Group Id and use tcsetpgrp to set the foreground process group:
1 # include <unistd. h> 2 3/* 4 obtain the foreground Process Group Id by opening the terminal's file descriptor 5 */6 pid_t tcgetpgrp (int fd ); 7 8/* 9 pgrpid must be a process group Id10 */11 int tcsetpgrp (int fd, pid_t pgrpid) in the same session );
For more information about session, process group, and controlling terminal, see The controlling-terminal and process-groups.
Job Control
Job control allows us to start multiple jobs in one terminal. We can control which jobs can access terminals and which jobs can run in the background. Job control requires support in the form of 3:
For us, when we use job control in shell, we can start the job on the front-end or back-end. A job is only a collection of processes, usually processes connected using pipeline. Example:
# Start jobvi main that contains a process on the foreground. c # all processes called by two background jobs are background processes pr *. c | lpr & make all & # When we start a background job, shell will assign a job id to this job, # And print one or more processes in the job IDs $ make all> Make. out & [1] 1475 $ pr *. c | lpr & [2] 1490
The terminal driver can recognize three special characters to generate signals sent to the foreground process group:
- Abort characters (usually DELETE or Crtl-C) to generate SIGINT
- Exit character (usually Crtl-Backslash) to generate SIGQUIT
- Pause characters (usually Crtl-Z) to generate SIGSTP
As mentioned above, only the foreground job receives terminal input, but it is not wrong for the background job to try to read the terminal, the Terminal Driver detects the background process and sends a special signal to the background job: SIGTTIN. SIGTTIN usually terminates the background job.
Summary
We have discussed the concepts that unix systems are closely related to process groups, sessions, foreground Process Groups, background process groups, control terminals, and job control. With this knowledge, we can understand how programs work in Unix systems and how they interact with users. We can even speculate that something happens in the system from the unix system to the normal running of the shell and the process of starting other processes in the shell. These should be indispensable for the underlying development of unix systems.