如何在fork()调用后仅打印一次程序整体实际运行时间?
问题:计算包含父子进程的程序整体运行时间,避免重复输出时间
原代码
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <math.h> #include <sys/time.h> #include <stdlib.h> void loopFunc(void) { for (int i = 0; i < 10000; i++) { int temp = pow(i, 2); } } int main(int argc, char *argv[]) { struct timeval begin, end; gettimeofday(&begin, 0); if (fork() == 0) { loopFunc(); printf("Child"); } else { loopFunc(); printf("Parent"); } gettimeofday(&end, 0); long seconds = end.tv_sec - begin.tv_sec; long microseconds = end.tv_usec - begin.tv_usec; double elapsed = seconds + microseconds * 1e-6; printf("Time measured: %.3f seconds.\n", elapsed); return 0; }
问题原因
fork()会创建一个与父进程几乎完全相同的子进程,父子进程会独立执行后续的所有代码,包括记录结束时间和打印运行时长的逻辑,因此会输出两次时间。而且原代码中计算的是单个进程从fork()前到自身执行完的时间,并非整个程序(父+子)的总运行时间。
解决方案
让父进程等待子进程执行完毕后,再统一计算并打印总运行时间,同时让子进程执行完任务后直接退出,不参与计时打印逻辑。修改后的代码如下:
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <math.h> #include <sys/time.h> #include <stdlib.h> void loopFunc(void) { for (int i = 0; i < 10000; i++) { int temp = pow(i, 2); } } int main(int argc, char *argv[]) { struct timeval begin, end; gettimeofday(&begin, 0); pid_t pid = fork(); if (pid == 0) { // 子进程:执行任务后直接退出,不处理计时 loopFunc(); printf("Child\n"); exit(0); } else if (pid > 0) { // 父进程:执行自身任务,等待子进程结束后计算总时间 loopFunc(); printf("Parent\n"); wait(NULL); // 阻塞等待子进程退出 gettimeofday(&end, 0); long seconds = end.tv_sec - begin.tv_sec; long microseconds = end.tv_usec - begin.tv_usec; double elapsed = seconds + microseconds * 1e-6; printf("Time measured: %.3f seconds.\n", elapsed); } else { // 处理fork失败的情况 perror("fork failed"); return 1; } return 0; }
关键修改点
- 用
pid_t保存fork()的返回值,增加了fork失败的错误处理,提升程序健壮性。 - 子进程执行完任务后调用
exit(0)直接退出,跳过后续的计时和打印逻辑。 - 父进程调用
wait(NULL),阻塞等待子进程完全执行完毕后,再记录结束时间并计算总运行时长,确保时间是整个程序从启动到所有进程结束的总耗时。 - 仅在父进程中执行计时结束和打印逻辑,避免重复输出。
内容的提问来源于stack exchange,提问作者Mustafa
相关产品推荐
相关产品推荐

