如何在C语言中基于命令行输入使用fork()、exec()创建子进程?
问题解答
你提供的示例代码存在多处错误,无法直接运行,具体问题如下:
- 语法错误:
fork()、wait4()调用后缺少分号;子进程判断的条件写为赋值语句pid = 0,应为相等判断pid == 0 execvp调用格式错误:你写的是函数声明而非实际调用,execvp的第一个参数为要执行的程序路径,第二个参数是完整的命令行参数数组(必须以NULL结尾)- 没有处理exec执行失败的场景:
execvp执行成功时不会返回,只有出错时才会返回,后续的exit(0)仅在执行失败时触发,建议补充错误打印 - 缺少时间统计逻辑:你注释里要求打印运行时间,需要配合
wait4返回的进程资源统计信息,或者自行记录进程运行前后的时间差
实现逻辑
你要实现的是类似time命令的功能,运行流程如下:
- 父进程读取命令行参数,比如你运行
./my_time ./loop 8,那么从argv[1]开始的所有参数都是要交给子进程执行的命令 - 父进程调用
fork()创建子进程 - 子进程调用
execvp()执行传入的命令,执行成功后子进程的代码会直接被替换为目标程序的代码 - 父进程调用
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
相关产品推荐
相关产品推荐

