[Linux operating system] In-depth exploration of Linux processes: creation, sharing and management

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.
insert image description here


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_tinteger 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 set errnoto 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_tinteger 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:

  1. int execl(const char *path, const char *arg, ...);

    • The argument pathis the path to the new program to execute.
    • argument argis a string representing the first argument to the new program.
    • The variable argument list is additional arguments for the new program and must NULLend with .
    • When the function executes successfully, it will not return. If it returns, it means that the execution failed.

  2. int execv(const char *path, char *const argv[]);

    • The argument pathis the path to the new program to execute.
    • arguments argvis an array of strings representing the argument list for the new program, the last element must be NULL.
    • When the function executes successfully, it will not return. If it returns, it means that the execution failed.

  3. int execle(const char *path, const char *arg, ..., char *const envp[]);

    • The argument pathis the path to the new program to execute.
    • argument argis a string representing the first argument to the new program.
    • The variable argument list is additional arguments for the new program and must NULLend with .
    • The argument envpis an array of strings representing the list of environment variables for the new program, the last element must be NULL.
    • When the function executes successfully, it will not return. If it returns, it means that the execution failed.

  4. int execvp(const char *file, char *const argv[]);

    • The argument fileis the filename of the new program to execute.
    • arguments argvis an array of strings representing the argument list for the new program, the last element must be NULL.
    • When the function executes successfully, it will not return. If it returns, it means that the execution failed.

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 -lthe 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.

  1. 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 statusis a pointer to an integer used to store the exit status information of the child process.
    • If the call fails, the function returns -1.

  2. pid_t waitpid(pid_t pid, int *status, int options);

    • The function suspends the current process until the specified child process ends.
    • Parameters pidSpecifies the process ID of the child process to wait on.
    • The parameter statusis a pointer to an integer used to store the exit status information of the child process.
    • The parameter optionsis 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 pidand .options

Among them, pidthe 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.

optionsParameters 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

  1. fork()Function: used to create a child process, different return values ​​indicate execution in different processes.
  2. 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.
  3. wait()And waitpid()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.
    • optionsYou 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.

Guess you like

Origin blog.csdn.net/Goforyouqp/article/details/132276890