跳至主要內容

40.多进程

约 379 字大约 1 分钟

创建多进程主要使用 fork()、exec()、wait() 这些系统调用

开启一个进程

#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid = fork();  // 创建子进程

    if (pid > 0) {
        printf("父进程: PID=%d, 子进程 PID=%d\n", getpid(), pid);
    } else if (pid == 0) {
        printf("子进程: PID=%d, 父进程 PID=%d\n", getpid(), getppid());
    } else {
        printf("fork 失败!\n");
    }
    return 0;
}

替换当前进程

execlp() 用 ls -l 替换当前进程,后续代码不会执行

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("执行 ls 命令...\n");
    execlp("ls", "ls", "-l", NULL);
    printf("这行不会执行!\n");
    return 0;
}

wait() 等待子进程结束

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
    pid_t pid = fork();
    if (pid > 0) {
        int status = 0;
        wait(&status);  // 等待子进程结束
        printf("子进程结束,状态: %d\n", status);
    } else if (pid == 0) {
        printf("子进程 PID=%d 正在运行...\n", getpid());
        sleep(10);
        printf("子进程结束\n");
    }
    return 0;
}

僵尸进程 & 孤儿进程

僵尸进程 子进程退出,但父进程未调用 wait(),导致进程表中仍保留信息

如何避免/解决
1.让父进程调用 wait() 或 waitpid()
2.使用 SIGCHLD 信号自动回收子进程

wait(&status);  // 阻塞等待子进程退出
waitpid(-1, &status, 0);  // 非阻塞等待
signal(SIGCHLD, SIG_IGN);  // 忽略子进程退出状态,自动清理僵尸进程

孤儿进程 父进程先退出,但子进程仍在运行

如何避免/解决
一般不需要处理,但可用 进程组 或 守护进程 方式管理