[Apue] Process Control (medium)

Source: Internet
Author: User
Tags posix terminates

One, wait, and WAITPID functions

A SIGCHLD signal is sent to the parent process when a process is normal or abnormally terminated. For this signal system is ignored by default. The process that calls Wait/waidpid may:

    • Blocking (if its child processes are still running);
    • Returns the terminating state of the child process immediately (if a child process has 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, the process may block when called at any one time.
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *statloc);pid_t waitpid(pid_t pid, int *statloc, int options);返回值: 成功返回进程ID, 出错-1.

The two functions differ:

    • Wait if the call is blocked before the child process terminates, and Waitpid has an option to keep the caller from blocking.
    • Waitpid does not wait for the first terminating child process-it has multiple options to control the process it waits for.

If the caller is blocked and it has more than one child process, wait returns as soon as it terminates. Because wait returns the child process ID, the caller knows which child process is terminated.
The parameter statloc is an integer pointer. If Statloc is not a null pointer, the terminating state is stored in the cell to which it points. If you do not care about the terminating state, set Statloc to a null pointer.
The integer states returned by these two functions are defined by the implementation. Some of these bits indicate the exit status (normal exit), the other bits indicate the signal number (abnormal return), one indicates whether a core file was produced, and so on. POSIX.1 specifies that the termination status is viewed by each macro defined in <sys/wait.h>. There are three mutually exclusive macros available to get the cause of the process termination, and their names have started with wif. Based on which of these three macros is true, you can choose a different macro (a macro other than three macros) to get the termination status, signal number, and so on.

The Pr_exit function in the following program uses the macros in the previous table to print the terminating state of the process.

#Include<sys/types.h>#Include<sys/wait.h>#Include<stdio.h>#Include<stdlib.h>voidPr_exit(int status) {if (wifexited (status)) {printf"Normal termination, Exit status=%d\n", Wexitstatus (status)); }Elseif (wifsignaled (status)) {printf"Abnormal termination, signal number =%d\n", Wtermsig (status),#Ifdef wcoredump wcoredump (status)?"(core file generated)":"");#Else"");#endif}Elseif (wifstopped (status)) {printf"Child stopped, signal number =%d\n", Wstopsig (status)); }}IntMain(void) {pid_t pid;int status;if (PID = fork ()) <0) {fprintf (StdErr"Fork Error"); }Elseif (PID = =0) {Exit7); }if (Wait (&status)! = pid) {fprintf (StdErr"Wait error"); } pr_exit (status);if (PID = fork ()) <0) {fprintf (StdErr"Fork Error"); }Elseif (PID = =0) {abort (); if (Wait (&status)! = pid) {fprintf (stderr, " wait error "); } pr_exit (status); if ((pid = fork ()) < 0) {fprintf (stderr,  "fork error");} else if (pid = = 0) {status/= 0; } if (Wait (&status)! = pid) {fprintf (stderr, " wait error "); } pr_exit (status); return 0;}         

Compile run Result:

Wait is returned whenever a child process terminates, and waitpid can specify that the child process waits. For waitpid PID parameters:

    • PID = =-1, waits for either child process. The waitpid is then equivalent to wait.
    • PID > 0, waiting for the child process ID to be PID.
    • PID = = 0, waiting for its group ID to be equal to any child process that invokes the group ID of the process.
    • PID <-1 waits for any child process whose group ID equals the absolute value of the PID.

For wait, the only error is that there is no child process (the function call is interrupted by one signal or another error may be returned).   For Waitpid, if the specified process or process group does not exist, or the calling process has no child processes, it can be faulted. The options parameter allows us to further control the operation of the Waitpid. This parameter is either 0, or a bitwise OR operation of the constants in the following table.

Ii. Conditions of race

When multiple processes attempt to do some sort of processing of a shared data, and the final result depends on the order in which the process is run, we think that this has a race condition (race condition). If some logic after the fork is explicitly or implicitly dependent on whether the parent process runs first or the child process after the fork, the fork function is the active habitat for the race condition.
If a process wants to wait for a child process to terminate, it must call the wait function. If a process waits for its parent process to terminate, the following forms of looping can be used:

while(getppid() != 1)    sleep(1);

The problem with this form of looping, called Periodic queries (polling), is that it wastes CPU time because the caller wakes every 1 seconds and then tests the condition.
To avoid race conditions and periodic queries, there is a need for some form of signaling mechanism between multiple processes. Signaling mechanisms can be used in Unix, and various forms of interprocess communication (IPC) can also be used.
In the relationship between the parent and child processes, there are often cases where the parent and child processes have something to do after the fork. For example, a parent process might update a record in a log file with a child process ID, and a child process might create a file for the parent process. In this case, each process is required to notify the other after it has performed a set of initialization operations and wait for the other party to complete its initialization before continuing. This situation can be described as follows:

TELL_WAIT();if ((pid = fork()) < 0) {    err_sys("fork error");} else if (pid == 0) { TELL_PARENT(getppid()); WAIT_PARENT(); exit(0);}TELL_CHILD(pid);WAIT_CHILD();exit(0);
C. exec function

When the process calls the EXEC function, the process is completely substituted by the new process, 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 simply replaces the body, data, heap, and stack segments of the current process with another program.

#Include<unistd.h>IntExecl(ConstChar *pathname,ConstChar *arg0, .../* (char *) 0 */);IntExecv(ConstChar *pathname,char *Const argv[]);IntExecle(ConstChar *pathname,ConstChar *arg0, .../* (char *) 0, char *const envp[] */);IntExecve(Constchar *pathname, char *const argv[ ], char *const envp[]); int EXECLP  (const char *filename, const char *arg0, ... /* (char *) 0 */); int EXECVP  (const char *filename, char *const argv[]); return value: Error-1, if successful does not return   

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 you make filename as a parameter:

    • If the filename contains/, it is treated as a path name.
    • Otherwise, press the PATH environment variable.

If either excelp and EXECVP found an executable file using one of the path prefixes, but the file is not a machine executable code file, it is considered a shell script, so try calling/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. Another three function execv,execvp,execve should construct an array of pointers to parameters, and then use the array address as a parameter to these three functions.
The last difference is related to passing the environment table to the new program. The two functions ending in e Excele and Exceve can pass a pointer to an array of environment string pointers. The other four functions use the Environ variable in the calling process to replicate the existing environment for the new program.
The difference between the six functions:

Each system has a limit on the total length of the parameter table and the Environment table. When you use the shell's file name extension to produce a file name table, you may receive a limit for this value. For example, command:

grep _POSIX_SOURCE /usr/include/*/*.h

The following forms of shell errors may be generated on some systems.

list too long

The process ID did not change after exec execution. In addition, the process of implementing the new procedure maintains the following characteristics of the original process:

    • The process ID and the parent process ID.
    • The actual user ID and the actual group ID.
    • Add the group ID.
    • The Process group ID.
    • The Conversation period ID.
    • Control terminal.
    • The time the alarm is still remaining.
    • Current working directory.
    • root directory.
    • File mode to create a masking word.
    • File lock.
    • Process signal masking.
    • Pending signal.
    • Resource limits.
    • Tms_utime,tms_stime,tms_cutime and Tms_ustime values.

Processing of open files is related to the exec close flag value for each descriptor. Each open descriptor in the process has an exec close flag. If this flag is set, the file descriptor is closed when exec executes, or the descriptor is still open. Unless this flag is specifically set with FCNTL, the default operation of the system is to leave this descriptor open after exec.
Posix.1 explicitly requires that the Open Directory stream be closed at exec. This is usually implemented by the OPENDIR function, which calls the FCNTL function to set the EXEC close flag for the descriptor that corresponds to the Open directory stream.
The actual user ID and the actual group ID before and after exec remain unchanged, and whether the valid ID changes depends on the settings of the file of the program being executed-the user-id bit and set-the group-id bit is set. If the new program's settings-user-id bit is set, the valid user ID becomes the ID of the owner of the program file, or the valid user ID is not changed. The group ID is handled in the same way.

In many UNIX implementations, only one execve of these six functions is a system call. The other 5 are library functions

[Apue] Process Control (medium)

Related Article

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.