Process creation is one of the important concepts in Linux system programming. In this section, we will introduce the creation of the process, obtaining the process ID and parent process ID, process sharing, exec function family, wait and waitpid and other related content.
Article Directory
1. Process creation
In Linux systems, processes are created using fork()
system calls. fork()
The system call will create a child process identical to the current process, and the child process will copy all the resources of the parent process, including code, data, and file descriptors.
1.1 Function prototype and return value
fork()
The prototype of the function is as follows:
#include <unistd.h>
pid_t fork(void);
fork()
The function has no parameters , and its return value is an pid_t
integer of type. The specific explanation is as follows:
- If the call is successful,
fork()
the function returns the PID (child process ID) of the child process in the parent process and 0 in the child process. - If the call fails,
fork()
the function returns -1 and is seterrno
to indicate the type of error.
1.2 Function examples
The code example is as follows:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
printf("Failed to fork a new process.\n");
return 1;
} else if (pid == 0) {
printf("This is the child process.\n");
} else {
printf("This is the parent process.\n");
}
return 0;
}
In the above code, fork()
the system call returns twice, in the parent process and in the child process respectively. By judging the return value, we can distinguish the parent process from the child process and execute different code logic.
2. Get process ID and parent process ID
In a Linux system, you can use getpid()
the and getppid()
system calls to get the ID of the current process and the ID of the parent process.
2.1 Function prototype and return value
getpid()
and getppid()
the prototype of the function is as follows:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
Both of these functions take no parameters , and both return an pid_t
integer of type . The specific explanation is as follows:
getpid()
The function returns the process ID (PID) of the calling process.getppid()
The function returns the process ID (PPID) of the parent process of the calling process.
2.2 Function Example
The code example is as follows:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid = getpid();
pid_t ppid = getppid();
printf("Process ID: %d\n", pid);
printf("Parent Process ID: %d\n", ppid);
return 0;
}
3. exec function family
In Linux systems, exec()
function families can be used to replace the current process with a new program. exec()
The function family includes execl()
, execv()
, execle()
, execve()
and other functions. These functions can perform different substitutions according to different parameter forms.
3.1 exec()
Common members of the function family:
-
int execl(const char *path, const char *arg, ...);
- The argument
path
is the path to the new program to execute. - argument
arg
is a string representing the first argument to the new program. - The variable argument list is additional arguments for the new program and must
NULL
end with . - When the function executes successfully, it will not return. If it returns, it means that the execution failed.
- The argument
-
int execv(const char *path, char *const argv[]);
- The argument
path
is the path to the new program to execute. - arguments
argv
is an array of strings representing the argument list for the new program, the last element must beNULL
. - When the function executes successfully, it will not return. If it returns, it means that the execution failed.
- The argument
-
int execle(const char *path, const char *arg, ..., char *const envp[]);
- The argument
path
is the path to the new program to execute. - argument
arg
is a string representing the first argument to the new program. - The variable argument list is additional arguments for the new program and must
NULL
end with . - The argument
envp
is an array of strings representing the list of environment variables for the new program, the last element must beNULL
. - When the function executes successfully, it will not return. If it returns, it means that the execution failed.
- The argument
-
int execvp(const char *file, char *const argv[]);
- The argument
file
is the filename of the new program to execute. - arguments
argv
is an array of strings representing the argument list for the new program, the last element must beNULL
. - When the function executes successfully, it will not return. If it returns, it means that the execution failed.
- The argument
These functions do not return when executed successfully, but directly replace the current process with a new program. If it returns, it means that the execution failed, and the error type can be judged according to the return value.
exec()
The function family can be used to load and execute new programs in the current process, and can realize dynamic switching and function expansion of programs. In general, exec()
the function family will fork()
be used after calling the function to create a child process to replace the code and data of the child process.
3.2 Function Example
The code example is as follows:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Before exec()\n");
execl("/bin/ls", "ls", "-l", NULL);
printf("After exec()\n");
return 0;
}
In the above code, execl()
the function will replace the current process with ls -l
the command. execl()
The first argument to the function is the program path to execute, and subsequent arguments are the command-line arguments passed to the new program.
4. wait和waitpid
In a Linux system, the parent process can use wait()
the or waitpid()
system call to wait for the end of the child process. These system calls block the execution of the parent process until the child process ends.
4.1 Function Explanation
wait()
and waitpid()
are functions to wait for the child process to end and get the exit status of the child process.
-
pid_t wait(int *status);
- The function suspends the current process until a child process terminates.
- If it successfully waits until the end of the child process, the function returns the process ID of the child process.
- The parameter
status
is a pointer to an integer used to store the exit status information of the child process. - If the call fails, the function returns -1.
-
pid_t waitpid(pid_t pid, int *status, int options);
- The function suspends the current process until the specified child process ends.
- Parameters
pid
Specifies the process ID of the child process to wait on. - The parameter
status
is a pointer to an integer used to store the exit status information of the child process. - The parameter
options
is an integer value that specifies options to wait for. - If the call fails, the function returns -1.
wait()
The return value of the and waitpid()
function is the process ID of the child process, or -1 if the call fails. The exit status information of the child process can be obtained through parameters status
, including exit code, termination signal, etc.
waitpid()
wait()
Functions are more flexible than functions, and can control the waiting subprocess through parameters pid
and .options
Among them, pid
the value of can be:
-1
: Wait for any child process.0
: Wait for a child process with the same process group ID as the current process.- Specific child process ID: wait for the specified child process.
options
Parameters can specify multiple options in the form of a bitmask. The commonly used options are:
WNOHANG
: Non-blocking mode, if no child process ends, return immediately.WUNTRACED
: Also returns the status of stopped subprocesses.WCONTINUED
: Also returns the status of child processes that have continued to run.
wait()
And waitpid()
functions can be used to handle the exit status of the child process, release the resources of the child process, and perform inter-process synchronization. When using these two functions, you need to pay attention to handling error conditions and avoiding the generation of zombie processes.
4.2 Function example
The code example is as follows:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
printf("Failed to fork a new process.\n");
return 1;
} else if (pid == 0) {
printf("This is the child process.\n");
} else {
wait(NULL);
printf("This is the parent process.\n");
}
return 0;
}
In the above code, the parent process uses wait(NULL)
a system call to wait for the end of the child process. wait()
A system call blocks the execution of the parent process until the child process terminates.
Summarize
fork()
Function: used to create a child process, different return values indicate execution in different processes.exec()
Function family: used to load and execute new programs in the current process, which can realize dynamic switching and function expansion of programs.execl()
: Accepts the form of variable parameters, and the parameters are passed in the form of strings.execle()
: Accepts the form of variable parameters and passes environment variables at the same time.execvp()
: Accepts the form of an array of parameters, and the parameters are passed in the form of a string array.
wait()
Andwaitpid()
function: used to wait for the end of the child process and get the exit status of the child process.wait()
: Wait for any child process to end.waitpid()
: You can specify the child process to wait for.- The exit status information of the child process can be obtained through the parameter
status
. options
You can control the waiting options through parameters, such as non-blocking mode, etc.- Care needs to be taken to handle error conditions and avoid spawning zombie processes.
These functions and system calls can be used to create, execute and wait for processes to achieve synchronization and collaboration between processes. Through these functions, dynamic process switching, function expansion and resource release can be realized. At the same time, you need to pay attention to handling error conditions to avoid zombie processes and resource leaks.