【Linux】【进程控制】API汇总整理

进程控制是操作系统中一个非常重要的概念,它涉及到创建、管理和终止进程的能力。进程控制包括一系列操作,如创建新进程、等待进程结束、发送信号给进程等。下面是进程控制中一些常见的操作及其相关API:

e8d212b67d804b07b0c6812f2be8c563.jpeg

进程控制概述

进程控制是指操作系统提供的用于管理进程生命周期的功能。这包括创建进程、获取进程状态、等待进程结束、发送信号等操作。这些功能对于编写多进程程序和系统管理工具尤为重要。

进程控制的常见操作

创建进程

  • fork()

    • pid_t fork(void): 创建一个新的进程,该进程是当前进程的一个副本。
    • 返回值:在父进程中返回子进程的PID,在子进程中返回0。
  • vfork()

    • pid_t vfork(void): 类似于fork(),但在子进程中执行完_exit()longjmp()前,父进程会被阻塞。
    • 返回值:同fork()
  • posix_spawn()

    • int posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]): 创建一个新的进程,执行指定路径的程序。
    • 参数argvenvp分别指定了程序的参数列表和环境变量。
  • exec系列函数

    • execl(const char *path, const char *arg, ...): 替换当前进程映像,执行新的程序。
    • execle(const char *path, const char *arg, ..., char *const envp[]): 替换当前进程映像,执行新的程序,并设置环境变量。
    • execlp(const char *file, const char *arg, ...): 替换当前进程映像,执行新的程序,使用PATH环境变量查找文件。
    • execv(const char *path, char *const argv[]): 替换当前进程映像,执行新的程序。
    • execvp(const char *file, char *const argv[]): 替换当前进程映像,执行新的程序,使用PATH环境变量查找文件。
    • execvpe(const char *file, char *const argv[], char *const envp[]): 替换当前进程映像,执行新的程序,使用PATH环境变量查找文件,并设置环境变量。
    • 返回值:这些函数在失败时返回-1,在成功时则不会返回。

获取进程状态

  • wait()

    • pid_t wait(int *status): 等待任意一个子进程结束,并获取其状态。
    • 参数status可以通过宏如WIFEXITED()WEXITSTATUS()等解析进程的状态。
  • waitpid()

    • pid_t waitpid(pid_t pid, int *status, int options): 等待指定的子进程结束,并获取其状态。
    • 参数pid可以指定等待哪个子进程;options可以指定等待的行为,如WNOHANG表示非阻塞等待。
  • waitid()

    • int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options): 等待一个指定的进程或线程结束,并获取其状态。
    • 参数idtype可以是P_PID(进程ID)、P_PGID(进程组ID)或P_PID(线程ID)。

进程终止

  • _exit()

    • _exit(int status): 使进程正常终止,并给出一个退出状态码。
    • 这个函数是进程终止时使用的,而不是用于线程。
  • exit()

    • void exit(int status): 使进程正常终止,并给出一个退出状态码。
    • 这个函数会先调用注册的终止处理函数。
  • abort()

    • void abort(void): 异常终止进程,并产生一个核心转储文件(如果启用了core dump)。

进程属性

  • getpid()

    • pid_t getpid(void): 获取当前进程的PID。
  • getppid()

    • pid_t getppid(void): 获取当前进程的父进程PID。
  • setsid()

    • pid_t setsid(void): 创建一个新的会话,并使其成为会话领导者。
    • 通常用于创建后台进程。
  • getpgid()

    • pid_t getpgid(pid_t pid): 获取进程组ID。
  • setpgid()

    • int setpgid(pid_t pid, pid_t pgid): 设置进程组ID。

进程资源控制

  • nice()

    • int nice(int inc): 改变进程的调度优先级。
    • inc表示优先级的变化值。
  • setpriority()

    • int setpriority(int which, id_t who, int prio): 改变进程或进程组的优先级。

发送信号

  • kill()

    • int kill(pid_t pid, int sig): 发送信号给指定的进程。
    • 参数sig指定要发送的信号类型。
  • raise()

    • int raise(int sig): 发送信号给当前进程。
    • 参数sig指定要发送的信号类型。

示例代码

以下是一个简单的示例,展示如何在 Linux 系统上使用 C 语言创建子进程、等待子进程结束、并获取子进程的退出状态:

1#include <stdio.h>
2#include <unistd.h>
3#include <sys/wait.h>
4
5int main() {
6    pid_t pid;
7
8    // 创建子进程
9    pid = fork();
10    if (pid < 0) {
11        fprintf(stderr, "fork failed\n");
12        return 1;
13    } else if (pid > 0) {
14        // 父进程
15        int status;
16
17        // 等待子进程结束
18        if (waitpid(pid, &status, 0) != pid) {
19            fprintf(stderr, "waitpid failed\n");
20            return 1;
21        }
22
23        // 检查子进程的退出状态
24        if (WIFEXITED(status)) {
25            printf("子进程正常退出,状态码为 %d\n", WEXITSTATUS(status));
26        } else {
27            printf("子进程异常退出\n");
28        }
29    } else {
30        // 子进程
31        printf("子进程 PID: %d\n", getpid());
32        _exit(0);  // 子进程正常退出
33    }
34
35    return 0;
36}

注意事项

  • 在创建子进程后,务必使用wait()waitpid()等待子进程结束,否则会产生僵尸进程。
  • 使用_exit()来终止子进程,而不要使用exit(),以避免执行不必要的清理工作。
  • 调用fork()之后,父进程和子进程中的程序计数器指向同一位置,因此通常需要立即添加条件分支来区分父进程和子进程的代码路径。
  • 在使用exec系列函数替换进程映像时,如果失败,需要检查错误并采取适当的措施。

进程控制是操作系统中的重要概念,理解这些操作对于编写多进程程序和系统管理工具至关重要。

猜你喜欢

转载自blog.csdn.net/suifengme/article/details/140752733