You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中基于命令行输入使用fork()、exec()创建子进程?

问题解答

你提供的示例代码存在多处错误,无法直接运行,具体问题如下:

  • 语法错误:fork()、wait4()调用后缺少分号;子进程判断的条件写为赋值语句pid = 0,应为相等判断pid == 0
  • execvp调用格式错误:你写的是函数声明而非实际调用,execvp的第一个参数为要执行的程序路径,第二个参数是完整的命令行参数数组(必须以NULL结尾)
  • 没有处理exec执行失败的场景:execvp执行成功时不会返回,只有出错时才会返回,后续的exit(0)仅在执行失败时触发,建议补充错误打印
  • 缺少时间统计逻辑:你注释里要求打印运行时间,需要配合wait4返回的进程资源统计信息,或者自行记录进程运行前后的时间差

实现逻辑

你要实现的是类似time命令的功能,运行流程如下:

  1. 父进程读取命令行参数,比如你运行./my_time ./loop 8,那么从argv[1]开始的所有参数都是要交给子进程执行的命令
  2. 父进程调用fork()创建子进程
  3. 子进程调用execvp()执行传入的命令,执行成功后子进程的代码会直接被替换为目标程序的代码
  4. 父进程调用wait4()等待子进程退出,同时获取子进程的运行时间、退出状态等信息

可运行的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>

int main(int argc, char *argv[]) {
    // 入参检查:至少需要传入要执行的命令
    if (argc < 2) {
        printf("用法:%s 命令 [参数...]\n", argv[0]);
        return 1;
    }

    pid_t pid = fork();
    if (pid < 0) {
        perror("fork失败");
        return -1;
    } else if (pid == 0) {
        // 子进程逻辑:执行传入的目标命令
        printf("我是子进程,pid:%d\n", getpid());
        // 从argv[1]开始就是要执行的命令和参数,C语言标准规定argv数组最后一位天然为NULL
        execvp(argv[1], argv + 1);
        // 只有exec执行失败才会走到这里
        perror("执行命令失败");
        exit(1);
    } else {
        // 父进程逻辑:等待子进程退出,统计运行时间
        int status;
        struct rusage usage;
        struct timeval start, end;
        // 记录实际运行时间起始点
        gettimeofday(&start, NULL);

        pid_t child_pid = wait4(pid, &status, 0, &usage);
        if (child_pid < 0) {
            perror("等待子进程失败");
            return 1;
        }

        gettimeofday(&end, NULL);
        double real_time = (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0;
        double user_time = usage.ru_utime.tv_sec + usage.ru_utime.tv_usec / 1000000.0;
        double sys_time = usage.ru_stime.tv_sec + usage.ru_stime.tv_usec / 1000000.0;

        printf("\n运行时间统计:\n");
        printf("实际时间:%.3f 秒\n", real_time);
        printf("用户态时间:%.3f 秒\n", user_time);
        printf("内核态时间:%.3f 秒\n", sys_time);

        if (WIFEXITED(status)) {
            printf("子进程正常退出,退出码:%d\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("子进程被信号终止,信号编号:%d\n", WTERMSIG(status));
        }
        return 0;
    }
}

使用方法

将上述代码编译后,运行./编译后的程序名 ./loop 8,即可实现需求:子进程执行./loop 8,父进程等待子进程终止后打印运行时间和退出状态。

内容的提问来源于stack exchange,提问作者TheKingSid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:24:02