Introduction:
For each process, there is a non-negative integer representing the unique process ID. Although the ID of a process is unique, it is reusable. There are some specialized processes in the system. A process such as ID 0 is usually a dispatch process, which is also a switching process or a system process (it is a kernel process). A process ID of 1 is typically the INIT process, which is a normal user process. Some functions related to the process ID:
#include <unistd.h>
pid_t getpid (void); //return value: Process ID of the calling process
pit_t getppid (void); //return value: The parent process ID of the calling process
uid_t getuid (void); //return value: The actual user ID of the calling process
uid_t geteuid (void); //return value: The valid group ID of the calling process
gid_t getgid (void); //return value: The valid user ID of the calling process
git_t getegid (void); //return value: The valid group ID of the calling process
A
An existing process can create a new process by calling the fork function. A new process created by Fork is called a child process. The fork function is called once, but returns two times. The only difference between the two returns is that the return value of the child process is 0, and the return value of the parent process is the process ID of the new child process. The child process and the parent process continue to execute the instruction after the fork call. A child process is a copy of the parent process. For example, a child process obtains a copy of the parent process data space, heap, and stack. Note that this is a copy owned by the child process. The parent-child process does not share these storage space portions. Parent-child processes share body segments. Many implementations do not perform a full copy of the parent process data segment, stack, and heap, since it is often followed by exec after fork. As an alternative, use write-time replication techniques.
The general use form of fork is as follows:
if (PID = fork ()) < 0) {//fork Create New process printf ("fork Error");} else if (PID = = 0) {//}else{//operation of the child process}
The differences between parent and child processes are:
The return value of fork is different; The process ID is different; two processes have different parent process IDs: The parent process ID of the child process is the ID of the process that created it, and the parent process ID is the same; the Tms_utime, Tms_stime, Tms_cutime, and Tms_ of the child process The ustime are set to 0. The file lock set by the parent process is not inherited by the quilt process. The unhandled alarm for the child process is cleared. The unhandled signal set of the child process is set to the empty.
In addition to inheriting the files opened by the parent process, the child process includes: actual user ID, actual group ID, valid user ID, valid group ID, additional group ID, process group ID, session ID, control terminal, storage mapping, and so on.
The fork will usually succeed, but it may also fail. The two main reasons that make fork fail are: 1, There are already too many processes in the system, 2, the total number of processes of the actual user ID exceeds the system limit.
Fork has the following two ways to use:
1. A parent process wants to replicate itself so that the parent and child processes execute different pieces of code at the same time. This is common in the Network service process-the parent process waits for the client's service request. When such a request arrives, the parent process calls fork to cause the child process to process the request. The parent process continues to wait for the next service request to arrive.
2, a process to execute a different program. This is a common scenario for the shell. In this case, the child process calls exec immediately after returning from the fork.
In addition to fork to create a new process, vfork is also used to create a new process:
The call sequence and the return value of the Vfork function are the same as the fork, but the semantics of the two are different from the following:
1. Vfork is used to create a new process, and the purpose of the new process is to exec a new program.
2. Vfork, like fork, creates a child process, but it does not completely copy the address space of the parent process into the child process, because the child process calls exec (or exit) immediately and therefore does not save the address space.
3. Another difference between vfork and fork is that vfork guarantees that the child process runs first, and the parent process may run after it calls exec or exit.
Two
A process is a life cycle, from being created to terminating. There are 8 ways to terminate a process, 5 normal termination methods, and 3 abnormal termination methods. Regardless of how the process terminates, the same piece of code in the kernel is executed at the end. This code closes all open descriptors for the corresponding process, frees the memory used by it, and so on.
Whether it is a normal termination or an abnormal termination, we want the terminating process to be able to notify its parent process how it terminated. For three terminating functions (exit, _exit, and _exit), this is accomplished by passing their exit state as a parameter to the function. In the case of an abnormal termination, the kernel (not the process itself) produces a terminating state that indicates the cause of its abnormal termination. In either case, the parent process of the terminating process can use the wait or Waitpid function to terminate the state. Note: The two terms "exit status" and "terminating state" are used here to indicate a difference. When the _exit is last called, the kernel transitions the exit state to the terminating state.
For the termination and exit status of the process, pay attention to the following points:
1. The child process is generated after the parent process calls fork, and the child process returns its terminating state to the parent process. However, if the parent process terminates before the child process, their parent process changes to Init to the city for all processes that the parent process has terminated. Said the process was adopted by the INIT process. The procedure is as follows: At the end of a process, the kernel examines all active processes individually to determine if it is the child process that is about to terminate the process, and if so, changes the process's parent process ID to 1.
2. If the child process terminates before the parent process, how can the parent process get the child process's terminating state when the corresponding check is made? A: The kernel holds a certain amount of information for each terminating process, so you can get this information when the parent process of the terminating process calls wait or waitpid. This information includes at least the process ID, the terminating state of the process, and the total amount of CPU time used by the process. The kernel can release all the stores that are used by the terminating process and close all of its open files. A process that has been terminated, but whose parent process has not yet dealt with it, is called a zombie process.
3. What happens when a process adopted by the INIT process terminates? Will it become a zombie process? No. Because Init is written so that whenever a child process terminates, Init invokes a wait function to its terminating state. When referring to "an init Wahabbi", this could refer to a process that was directly generated by INIT, or that the parent process had been terminated by the INIT adoption process.
Three
When a process is normal or abnormally terminated, the kernel sends a SIGCHLD signal to its parent process. Because the child process termination is an asynchronous event, this signal is also an asynchronous notification that the kernel sends to the parent process. The parent process can choose to ignore the signal, or provide a Hansu (signal handler) that is invoked to execute when the signal occurs. The system defaults to ignoring it. What you need to know now is what happens to the process that calls wait or waitpid:
1. Block if all of its child processes are still running.
2. If a child process is terminated and is waiting for the parent process to get its terminating state, the terminating state of the child process is returned immediately.
3. If it does not have any child processes, an immediate error is returned.
#include <sys/types.h>
#include <sys/wait.h>
pid_t Wait (int *status);
pid_t waitpid (pid_t pid, int *status, int options); Return value: Returns the process id,0 if successful, and returns 1 if an error occurs
The differences between the two functions are:
1. Before a child process terminates, wait causes its callers to block, and Waitpid has an option that allows the caller to not block.
2. Waitpid does not wait for the first terminating child process after its invocation, and it has several options to control the process it waits for.
The parameter status of a function is an integer pointer. If the status is not a null pointer, the termination state of the terminating process is stored in the cell to which it points. If you do not care about the terminating state, you can specify the parameter as a null pointer. There are 4 macros that check the termination status returned by wait or waitpid: wifexited (status), wifsignaled (status), wifstopped (status), wifontinued (stauts).
The Waitpid function provides three features that the wait function does not provide:
1. Waitpid can wait for a specific process, while wait returns the state of either terminating child process.
2. Waitpid provides a non-blocking version of wait. Sometimes the user wants to get the status of a child process, but does not want to block.
3, WAITPID support operation control.