Several methods and comparison for starting a new process in Linux

Source: Internet
Author: User
Tags types of functions
Sometimes, we need to start another program (process) in our own program to help us complete some work, so how do we start other processes in our own processes? In Linux, many methods are provided to achieve this. The following describes the differences between these methods. 1. the prototype of the system function called by the system function is:
#include <stdlib.h>int system (const char *string);
Its function is to run the command passed to it as a string parameter and wait for the completion of the command. The command execution is like executing the command in shell: Sh-C string. If the shell cannot be started to run this command, the system function returns Error Code 127. If it is another error,-1 is returned. Otherwise, the system function returns the exit code of the command. Note: The system function call uses a shell to start the program to be executed, so you can put this program in the background for execution. Here, the system function call will return immediately. The following example shows the source file new_ps_system.c. The Code is as follows:
# Include <stdlib. h> # include <stdio. h> int main () {printf ("Running ps with SYSTEM \ n"); // return after the PS process ends, to continue executing the following code system ("PS au"); // 1 printf ("PS done \ n"); exit (0 );}
The program calls the PS program to print all processes related to the user, and finally prints the PS done. The running result is as follows: if the statement of comment 1 is changed to: System ("PS au &"); then the system function returns immediately, and the following code can be executed without waiting for the PS process to finish. So the output you see may not appear in the last line, but in the middle. Generally, using the system function is not an ideal method to start other processes, because it must use a shell to start the required program, that is, a shell needs to be started before the program starts, it also relies heavily on the shell environment, so the efficiency of using the system function is not high. 2. Replace the process image-the exec series functions are composed of a group of related functions, which have different methods of starting processes and expressing program parameters. However, all exec functions work in the same way. They replace the current process with a new process. That is to say, you can use the exec function to switch the execution of a program from one program to another, after the new program starts, the original program will no longer be executed. The new process is specified by the path or file parameter. Exec functions are more effective than system functions. Exec functions are of the following type:
#include <unistd.h>char **environ;int execl (const char *path, const char *arg0, ..., (char*)0);int execlp(const char *file, const char *arg0, ..., (char*)0);int execle(const char *path, const char *arg0, ..., (char*)0, char *const envp[]);int execv (const char *path, char *const argv[]);int execvp(cosnt char *file, char *const argv[]);int execve(const char *path, char *const argv[], char *const envp[]);
These types of functions can be divided into two categories. The parameters of execl, execlp, and execle are variable and end with a null pointer, while the second parameters of execv, execvp, and execve are a string array, when a new process is called, argv serves as the parameter of the main function of the new process. However, envp can be used as the environment variable of the new process and passed to the new process to variable its available environment variable. In the previous example, if you want to use the exec system function to start the PS process, the calling statements for the six different functions are: Note: arg0 is the program name, so in this example, all is ps.
char *const ps_envp[] = {"PATH=/bin:usr/bin", "TERM=console", 0};char *const ps_argv[] = {"ps", "au", 0};execl("/bin/ps", "ps", "au", 0);execlp("ps", "ps", "au", 0);execle("/bin/ps", "ps", "au", 0, ps_envp);execv("/bin/ps", ps_argv);execvp("ps", ps_argv);execve("/bin/ps", ps_argv, ps_envp);
The following is a complete example. The source file is new_ps_exec.c and the code is as follows:
#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(){printf("Running ps with execlp\n");execlp("ps", "ps", "au", (char*)0);printf("ps Done");exit(0);}
The running result is as follows: if you are careful, you can find that the last PS done is not output. Is this accidental? Therefore, the statement printf ("PS
Done "); there is no chance of execution. Note: In general, the exec function will not return unless an error is returned-1. The new process started by Exec inherits many of the features of the original process, the file descriptor opened in the original process will remain open in the new process, but any directory stream opened in the original process will be closed in the new process. 3. Copy the process image-fork function 1. The application exec call of fork function replaces the currently executed process with a new process, and we can also use fork to copy a new process, the new process is almost identical to the original process, and the executed code is also identical, but the new process has its own data space, environment, and file descriptor. The prototype of the fork function is:
#include <sys/type.h>#include <unistd.h>pid_t fork();
Note: In the parent process, fork returns the PID of the new Child process, and fork in the child process returns 0. We can use this to determine the parent process and child process, if the fork call fails, it returns-1. inherit from the above example. Here is an example of calling ps. The source file is new_ps_fork.c. The Code is as follows:
# Include <unistd. h> # include <sys/types. h> # include <stdio. h> # include <stdlib. h> int main () {pid_t pid = fork (); Switch (PID) {Case-1: perror ("fork failed"); exit (1); break; case 0: // This is in the sub-process, call execlp to switch to PS process printf ("\ n"); execlp ("Ps", "Ps", "au ", 0); break; default: // This is the message printf ("parent, PS done \ n"); break;} exit (0 );}
The output result is: we can see that PS done that was not shown in the second point is printed, but the sequence is a bit wrong, because the parent process is executed before the subroutine, therefore, the parent and PS done are output first. Is there any way to output the parent and PS done after the sub-process is output? Of course, the wait and waitpid functions are used. Note: Generally, the life cycle of the parent process and the child process is irrelevant. Even if the parent process exits, the child process can still run normally. 2. the prototype of the wait and waitpid functions waiting for a process is as follows:
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *stat_loc);pid_t waitpid(pid_t pid, int *stat_loc, int options);
Wait is called in the parent process to suspend the execution of the parent process and wait for the completion of the Child process. The PID of the child process is returned. If stat_loc is not a null pointer, the status information will be written to the location pointed to by stat_loc. Waitpid waits for the completion of a sub-process whose ID is PID (PID is-1 and information of any sub-process is returned). The stat_loc parameter serves the same purpose as the wait function, options is used to change the waitpid behavior. Among them, wnohang is an important option to prevent the waippid caller from suspending the execution. If the child process is not terminated or unexpectedly terminated, it returns 0; otherwise, the child process PID is returned. The changed program is saved as the source file new_ps_fork2.c. The Code is as follows:
# Include <unistd. h> # include <sys/types. h> # include <stdio. h> # include <stdlib. h> int main () {pid_t pid = fork (); int stat = 0; Switch (PID) {Case-1: perror ("fork failed "); exit (1); break; Case 0: // This is in the sub-process, call execlp to switch to PS process printf ("\ n"); execlp ("Ps ", "PS", "au", 0); break; default: // This is in the parent process, waiting for the child process to end and outputting the relevant prompt information pid = wait (& Stat ); printf ("child has finished: pid = % d \ n", pid); // check the sub-process exit status if (wifexited (STAT )) printf ("Child exited with code % d \ n", wexitstatus (STAT); elseprintf ("Child terminated abnormally \ n"); printf ("parent, PS done \ n "); break;} exit (0 );}
Output: we can see that the output is finally normal, and the output of parent is also after the output of the sub-process. Conclusion: The comparison between the three methods for starting a new process is the simplest system function. It needs to start a new shell and execute sub-processes in the new shell, therefore, the environment is highly dependent and the efficiency is not high. At the same time, the system function can execute the following statement only after the sub-process returns. The exec system function replaces the original process with a new process, which is more efficient, but it does not return to the original process. That is to say, the code after the exec function will not be executed, unless the exec call fails. However, the new process started by Exec inherits many features of the original process, and the opened file descriptor will remain open in the new process, any directory stream opened in the original process will be closed in the new process. Fork uses the current process to reproduce a new process. The new process is the same as the original process, and the executed code is also the same, however, new processes have their own data space, environment variables, and file descriptors. We usually determine whether the current process is a child process or a parent process based on the return value of the fork function, that is, it does not return as exec does, but returns a pid_t value for judgment. We can continue to execute the code after fork. We feel that using the fork and exec functions can create many processes that are required.

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.