Linux c Note Process Control (iii)

Source: Internet
Author: User
Tags signal handler terminates

Process exit
The process end indicates that the process is about to end, and the process exit methods in the Linux system are divided into normal exit and exception exit.
Exit function
The process has three normal termination methods and two kinds of abnormal termination methods.
(1) Normal termination:
(a) Execute the return statement within the main function. This is equivalent to calling exit.
(b) Call the Exit function. This function is defined by ANSI C, which includes calling each termination handler (the terminating handler logs on when the Atexit function is called), and then shutting down all standard I/O flows. Because ANSI C does not handle file descriptors, multiple processes (parent, child processes), and job control, this definition is incomplete for UNIX systems.
(c) Call the _exit system call function. This function is called by exit, which handles UNIX-specific details.
(2) Abnormal termination:
(a) Call abort. It generates a SIGABRT signal, so it is a special case of the next abnormal termination.
(b) When a process receives a signal, and the signal causes the program to terminate. The process itself (such as calling the Abort function), other processes, and the kernel can produce signals that are transmitted to a process. For example, if a process accesses a storage unit with its address space, or is divided by 0, the kernel generates a corresponding signal for that process.
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.

Comparison of exit modes:
The difference between exit and return: Exit is a function with parameters, return is returned after the function has been executed, exit gives control to the system, and return gives control to the calling function
Exit and about the difference: Exit is the normal termination procedure, about is the abnormal termination program
Exit (int exit_code): The parameter Exit_code in exit is 0 for normal termination of the process, and if other values indicate an error occurred during program execution, such as: overflow, divisor 0.
The difference between exit () and _exit (): Exit is declared in the header file Stdlib.h, and _exit () declares that in the header file Unistd.h, two functions terminate the process normally, but _exit () returns to the kernel immediately after execution, and exit () To do some cleanup first, then give control to the kernel.

For any of these termination scenarios, we want the terminating process to be able to notify its parent process how it terminated. For exit and _exit, this is accomplished by relying on the exit status parameter passed to them. In an abnormal termination condition, the kernel (not the process itself) produces a terminating state (termination status) that indicates the cause of its abnormal termination. In either case, the parent process of the terminating process can have its terminating state with the wait or Waitpid function.
Note that the "Exit status" (which is the argument passed to exit or _exit, or the return value of main) and the "terminating state" two terms are used here to indicate a difference. In the last call to _exit, the kernel transitions its exit state to a terminating state. The different ways that the parent process checks the terminating state of a child process. If the child process terminates normally, the parent process can get the exit status of the child process.

When explaining the fork function, it must be a parent process that generates a child process. It also shows that 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 the INIT process for all processes whose parent process has been terminated. We call these processes adopted by the INIT process. The process is generally: at the end of a process, the kernel examines all active processes individually to determine if it is a child of the process being terminated, and if so, the process's parent process ID is changed to 1 (i D of the init process). This approach ensures that each process has a parent process.
  
Another thing we care about is if the child process terminates before the parent process, then how can the parent process get the child process's terminating state when the corresponding check is made? The answer to this question is that the kernel holds a certain amount of information for each terminating child process, so when the parent process of the terminating process calls wait or waitpid, Can get information about it. This information includes at least the process ID, the terminating state of the process, and the total amount of CPU time used against the process. The kernel can release all the memory used to terminate the process and close all of its open files. In UNIX terminology, a process that has been terminated, but whose parent process has not yet dealt with it (getting information about terminating a child process, releasing resources it still occupies) is called a Zombie process (zombie). If you write a long-running program that fork a lot of child processes, the child processes become zombie unless the parent process waits for the child process to terminate.


To execute a new program:
exec function
After a child process is created with the fork function, the child process often calls an EXEC function to execute another program. When a process invokes an EXEC function, the process is completely substituted by the new program, and the new program executes from its main function.
Because calling exec does not create a new process, the process ID before and after does not change. EXEC just replaces the body, data, heap, and stack segments of the current process with another new program.
There are six different exec functions to use, and they are often referred to as the EXEC function. These exec functions are the UNIX Process Control primitives. Fork allows you to create a new process with exec to execute the new program. Exit Function and two wait function processing
Terminate and wait for termination. These are the basic process control primitives that we need. These primitives will be used in subsequent sections to construct additional functions such as popen and system.
#include <unistd.h>
int execl (const char * pathname, const char *arg 0, .../* (char *) 0 */);
int execv (const char *pathname, char * const argv []);
int execle (const char * pathname, const char * arg 0, ...);
int Execve (const char * pathname, char * const argv [], char * const ENVP []);
int EXECLP (const char * filename, const char *arg 0, .../* (char *) 0 */);
int EXECVP (const charfile * name, char * const argv []);
Six function returns: 1 if there is an error, no return if successful


The first difference between these functions is the top four takes the path name as the parameter, and the last two take the file name as the parameter. When
When you specify filename as a parameter:
• If the filename contains/, it is treated as a path name.
• Otherwise, follow the PATH environment variable to search for the executable file in the relevant directory.
The path variable contains a table of contents (known as a path prefix) separated by a colon (:) between the directories. For example, the following name = value Environment string: Path=/bin:/usr/bin:/usr/local/bin:.
Specifies that a search be made in four directories. (The 0 long prefix also represents the current directory.) Available at the beginning of value: represents, in the middle of the line, with:: Representation, at the end of the line with: representation. )

If either EXECLP and EXECVP found an executable file using one of the path prefixes, but the file is not a machine executable code file generated by the connection editor, it is considered a shell script, and then tries to invoke/bin/sh, and takes the filename as input to the shell.
The second difference is related to the passing of the parameter table (L represents the table (list), and V represents the vector). The functions execl, EXECLP, and execle require that each command-line argument of the new program be described as a separate parameter. This parameter table ends with a null pointer.
For the other three functions (EXECV, EXECVP, and Execve), you should construct a pointer array to each parameter, and then use that array address as an argument for these three functions.
Before using ANSI C prototypes, the general method for Execl, Execle, and EXECLP three functions to represent command-line arguments is: char * arg 0, char * arg 1, ..., char * arg n, (char *) 0
It should be noted that after the last command-line argument, a null pointer is followed. If a null pointer is represented by a constant zero, it must be cast to a character pointer, otherwise it will be interpreted as an integer parameter. If the length of an integer is different from the length of char *, the EXEC function's actual argument will be faulted.
The last difference is related to passing the environment table to the new program. The two functions (Execle and EXECVE) ending with E can pass a pointer to an array of environment string pointers. The other four functions are used in the calling process
The Environ variable copies the existing environment for the new program. Typically, a process allows its environment to be propagated to its child processes, but sometimes it is the case that the process wants to specify a certain environment for the child process. For example, when initializing a newly logged-in shell, the login program creates a special environment that defines only a few variables, and when we log on, we can start the file with the shell and add other variables to the environment


Environment variables
Environment variables (environment variables) are typically used in the operating system to specify the operating system environment of some parameters, such as: temporary folder location and System folder location.
An environment variable is an object with a specific name in the operating system that contains the information that one or more applications will use. For example, the PATH environment variable in Windows and DOS operating system, when the system is required to run a program without telling it the full path of the program, in addition to the current directory in the search for this program, but also in path specified in the path to find. The user can run the process better by setting the environment variables.
As mentioned earlier, the environment string is in the form of:
Name = value
The Unix kernel does not care about the meaning of this string, and their interpretation depends entirely on the individual applications. For example, the shell uses a large number of environment variables. Some of these are set automatically at login (such as home,user, etc.), while others are set by the user. We typically set environment variables in a shell start file to control the action of the shell. For example, if you set the environment variable Mailpath, it tells Bourne where the shell and KornShell go to see the message.
ANSI c defines a function getenv, which can be used to take the value of an environment variable, but the standard also says that the content of the environment is defined by the implementation.
#include <stdlib.h>
char * GETENV (const char * name);
Returns: A pointer to the value associated with name, or NULL if not found
Note that this function returns a pointer to value in the name = value string. Instead of directly accessing environ, we should use getenv to take the value of an environment variable from the environment.


Execv function: The EXECV function calls the executable file as a new process image by way of the pathname. His argv parameter is used to provide the ARGV parameter to the main function. The argv parameter is a string array that ends with a null (the last element must be a null pointer)
Execve function: In this system, the parameter path is the path name of the program that will be executed, and the parameter argv,envp corresponds to the argv,envp of the main function.
execl function: This function is similar to the use of the EXECL function, except when the parameter is passed ("... "Indicates that the number of parameters is indeterminate), it is important to note that these parameters are to end with a null pointer
execl function: This function is similar to the use of the EXECL function, except to explicitly specify an environment variable. The environment variable is behind the last parameter of the command-line argument, after the null pointer.
EXECVP function: This function is similar to the EXECV function, unlike the parameter filename. If the attendee contains "/", it is the path name, and if it does not contain "/", the function looks for the executable file in the directory defined by the PATH environment variable, separated by a colon from the directory of the PATH environment variable.
EXECLP function: This function is similar to the EXECL function, and their difference is the same as the difference between EXECVP and EXECV.

of the 6 functions of the EXEC function family, only EXECVE is a system call, the other five are library functions, and they are implemented with a call to Execve




The process has maintained many of its original features in addition to the original process ID, the parent process ID, the actual user ID, and the actual group ID after the new program was executed, mainly:
. Current working directory
. root directory
. Create a file that is used by the mask word
. Process Signal Screen Word
. Pending warnings
. Process-related time to use the processor
. Control Terminal
. File lock

Wait for process to end
When a child process exits before the parent process, the child process enters a zombie state if the parent process does not call the wait and WAITPID functions. If the parent process calls the wait and WAITPID functions, it does not turn the child process into a zombie process, which
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 (which can occur at any time the parent process runs), this signal is also an asynchronous notification that the kernel sends to the parent process. The parent process can ignore the signal, or provide a function (signal handler) that is called to execute when the signal occurs. The system default action for this signal is to ignore it. Processes that call wait or waitpid may:
• Blocking (if all of its child processes are still running).
• The termination state of the tape process returns immediately (if a child process has been terminated and is waiting for the parent process to access its terminating state).
• An error is returned immediately (if it does not have any child processes).
If a process calls wait because it receives a SIGCHLD signal, you can expect wait to return immediately. However, if you call wait at any one time, the process may block.
#include <sys/types.h>
#include <sys/wait.h>
pid_t Wait (int *statloc);
pid_t waitpid (pid_t pid, int * statloc, int options);
Two function returns: the process ID if successful, or 1 if there is an error

• Before a child process terminates, wait causes its callers to block, and Waitpid has a selection that allows the caller to not block.
Waitpid does not wait for the first terminating child process-it has several choices that can control the process it waits for.

If a child process is terminated and is a zombie process, wait immediately returns and gets the state of the child process, otherwise w a i t causes its caller to block until a child process terminates. If the caller is blocked and it has more than one child process, wait returns immediately at the end of its subprocess. Because wait returns the process ID of the terminating child process, it always knows which child process is terminated.

The parameter statloc of these two functions is an integer pointer. If the statloc is not a null pointer, the terminating 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.
Traditionally, the integer state words returned by these two functions are defined by the implementation. Some of these bits indicate the exit status (normal return), the other bits indicate the signal number (abnormal return), one indicates whether a core file was produced, and so on.







The explanation of PID parameters for Waitpid is related to its value:
PID = =-1 waits for either child process. So waitpid is equivalent to wait in this function.
pid > 0 A child process that waits for its process ID to be equal to the PID.
pid = = 0 waits for its group ID to be equal to any of the child processes that call the process's group I d.
PID <-1 waits for any sub-process whose group ID equals the absolute value of the PID.
Waitpid returns the process ID of the terminating child process, and the terminating state of the child process is returned through Statloc. For wait, the only error is that the calling process has no child processes (when a function call is interrupted by one signal, another error may be returned.) However, for Waitpid, if the specified process or process group does not exist, or the calling process has no child processes, an error can occur.
The options parameter allows us to further control the operation of the Waitpid. This parameter is either 0, or the constant in table 8-2 is
Bit or operation.

The Waitpid function provides three features that the wait function does not provide:
(1) Waitpid waits for a specific process (while wait returns the state of either terminating child process).
(2) Waitpid provides a non-blocking version of wait. Sometimes you want to get the state of a child process, but you don't want to block.
(3) Waitpid support job control (with wuntraced selection).

Linux C Note Process Control (iii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.